Attribute VB_Name = "basUnsignedWord"
Option Explicit
' basUnsignedWord: Utilities for unsigned word arithmetic
' Version 6.1. June 2008. Fixed overflow problem in uw_WordAdd
' Version 6. November 2003. Unchanged from Version 5.
' Version 5. January 2002. Replaced uw_WordSplit and uw_WordJoin
' with more efficient uwSplit and uwJoin.
' Version 4. 12 May 2001. Mods to speed up.
' Thanks to Doug J Ward and Ernie Gibbs for advice and suggestions.
'************************* COPYRIGHT NOTICE*************************
' This code was originally written in Visual Basic by David Ireland
' and is copyright (c) 2000-8 D.I. Management Services Pty Limited,
' all rights reserved.
' You are free to use this code as part of your own applications
' provided you keep this copyright notice intact and acknowledge
' its authorship with the words:
' "Contains cryptography software by David Ireland of
' DI Management Services Pty Ltd <www.di-mgt.com.au>."
' If you use it as part of a web site, please include a link
' to our site in the form
' <A HREF="http://di-mgt.com.au/crypto.html">Cryptography
' Software Code</a>
' This code may only be used as part of an application. It may
' not be reproduced or distributed separately by any means without
' the express written permission of the author.
' David Ireland and DI Management Services Pty Limited make no
' representations concerning either the merchantability of this
' software or the suitability of this software for any particular
' purpose. It is provided "as is" without express or implied
' warranty of any kind.
' Please forward comments or bug reports to <code@di-mgt.com.au>.
' The latest version of this source code can be downloaded from
' www.di-mgt.com.au/crypto.html.
'****************** END OF COPYRIGHT NOTICE*************************
Private Const OFFSET_4 = 4294967296#
Private Const MAXINT_4 = 2147483647
Public Function uwJoin(a As Byte, b As Byte, C As Byte, d As Byte) As Long
' Added Version 5: replacement for uw_WordJoin
' Join 4 x 8-bit bytes into one 32-bit word a.b.c.d
uwJoin = ((a And &H7F) * &H1000000) Or (b * &H10000) Or (CLng(C) * &H100) Or d
If a And &H80 Then
uwJoin = uwJoin Or &H80000000
End If
End Function
Public Sub uwSplit(ByVal w As Long, a As Byte, b As Byte, C As Byte, d As Byte)
' Added Version 5: replacement for uw_WordSplit
' Split 32-bit word w into 4 x 8-bit bytes
a = CByte(((w And &HFF000000) \ &H1000000) And &HFF)
b = CByte(((w And &HFF0000) \ &H10000) And &HFF)
C = CByte(((w And &HFF00) \ &H100) And &HFF)
d = CByte((w And &HFF) And &HFF)
End Sub
' Function re-written 11 May 2001.
Public Function uw_ShiftLeftBy8(wordX As Long) As Long
' Shift 32-bit long value to left by 8 bits
' i.e. VB equivalent of "wordX << 8" in C
' Avoiding problem with sign bit
uw_ShiftLeftBy8 = (wordX And &H7FFFFF) * &H100
If (wordX And &H800000) <> 0 Then
uw_ShiftLeftBy8 = uw_ShiftLeftBy8 Or &H80000000
End If
End Function
Public Function uw_WordAdd(wordA As Long, wordB As Long) As Long
' Adds words A and B avoiding overflow
Dim myUnsigned As Double
myUnsigned = LongToUnsigned(wordA) + LongToUnsigned(wordB)
' Cope with overflow
' [2008-06-25] Changed "> OFFSET_4" to ">= OFFSET_4'
' -- thanks to Ernie Gibbs for this.
If myUnsigned >= OFFSET_4 Then
myUnsigned = myUnsigned - OFFSET_4
End If
uw_WordAdd = UnsignedToLong(myUnsigned)
End Function
Public Function uw_WordSub(wordA As Long, wordB As Long) As Long
' Subtract words A and B avoiding underflow
Dim myUnsigned As Double
myUnsigned = LongToUnsigned(wordA) - LongToUnsigned(wordB)
' Cope with underflow
If myUnsigned < 0 Then
myUnsigned = myUnsigned + OFFSET_4
End If
uw_WordSub = UnsignedToLong(myUnsigned)
End Function
'****************************************************
' These two functions from Microsoft Article Q189323
' "HOWTO: convert between Signed and Unsigned Numbers"
Function UnsignedToLong(value As Double) As Long
If value < 0 Or value >= OFFSET_4 Then Error 6 ' Overflow
If value <= MAXINT_4 Then
UnsignedToLong = value
Else
UnsignedToLong = value - OFFSET_4
End If
End Function
Public Function LongToUnsigned(value As Long) As Double
If value < 0 Then
LongToUnsigned = value + OFFSET_4
Else
LongToUnsigned = value
End If
End Function
' End of Microsoft-article functions
'****************************************************