<div style="text-indent: 2em;">

在C和Java等编程语言中,可以方便地对变量进行移位运算,但是在VB中,却没有内置的移位运算符或者函数。

于是,我们得自己动手编写移位的运算函数。原理很简单,每向右移一位,就将被移位的变量的二进制除以2;每向左移一位,就将被移位的变量的二进制乘以2。于是可以写出以下函数:

    '
    ' 按位左移
    '
    Public Function LShift(ByVal val, ByVal n)
        LShift = val * 2 ^ n
    End Function
'
' 按位右移
'
Public Function RShift(ByVal val, Byval n) 
    RShift = val \ (2 ^ n)
End Function

以上写的两个左移和右移函数,非常简单,没有考虑机器字长以及传过来的变量类型等。

后来看到在VBS的MD5加密算法中,包含左移右移的函数,在这里,将它们单独拧出来,以作为左移右移函数的升级版本:

Private m_lOnBits(30)
Private m_l2Power(30)

Private Function Initialize()      m_lOnBits(0) = CLng(1)     m_lOnBits(1) = CLng(3)     m_lOnBits(2) = CLng(7)     m_lOnBits(3) = CLng(15)     m_lOnBits(4) = CLng(31)     m_lOnBits(5) = CLng(63)     m_lOnBits(6) = CLng(127)     m_lOnBits(7) = CLng(255)     m_lOnBits(8) = CLng(511)     m_lOnBits(9) = CLng(1023)     m_lOnBits(10) = CLng(2047)     m_lOnBits(11) = CLng(4095)     m_lOnBits(12) = CLng(8191)     m_lOnBits(13) = CLng(16383)     m_lOnBits(14) = CLng(32767)     m_lOnBits(15) = CLng(65535)     m_lOnBits(16) = CLng(131071)     m_lOnBits(17) = CLng(262143)     m_lOnBits(18) = CLng(524287)     m_lOnBits(19) = CLng(1048575)     m_lOnBits(20) = CLng(2097151)     m_lOnBits(21) = CLng(4194303)     m_lOnBits(22) = CLng(8388607)     m_lOnBits(23) = CLng(16777215)     m_lOnBits(24) = CLng(33554431)     m_lOnBits(25) = CLng(67108863)     m_lOnBits(26) = CLng(134217727)     m_lOnBits(27) = CLng(268435455)     m_lOnBits(28) = CLng(536870911)     m_lOnBits(29) = CLng(1073741823)     m_lOnBits(30) = CLng(2147483647)          m_l2Power(0) = CLng(1)     m_l2Power(1) = CLng(2)     m_l2Power(2) = CLng(4)     m_l2Power(3) = CLng(8)     m_l2Power(4) = CLng(16)     m_l2Power(5) = CLng(32)     m_l2Power(6) = CLng(64)     m_l2Power(7) = CLng(128)     m_l2Power(8) = CLng(256)     m_l2Power(9) = CLng(512)     m_l2Power(10) = CLng(1024)     m_l2Power(11) = CLng(2048)     m_l2Power(12) = CLng(4096)     m_l2Power(13) = CLng(8192)     m_l2Power(14) = CLng(16384)     m_l2Power(15) = CLng(32768)     m_l2Power(16) = CLng(65536)     m_l2Power(17) = CLng(131072)     m_l2Power(18) = CLng(262144)     m_l2Power(19) = CLng(524288)     m_l2Power(20) = CLng(1048576)     m_l2Power(21) = CLng(2097152)     m_l2Power(22) = CLng(4194304)     m_l2Power(23) = CLng(8388608)     m_l2Power(24) = CLng(16777216)     m_l2Power(25) = CLng(33554432)     m_l2Power(26) = CLng(67108864)     m_l2Power(27) = CLng(134217728)     m_l2Power(28) = CLng(268435456)     m_l2Power(29) = CLng(536870912)     m_l2Power(30) = CLng(1073741824) End Function 

Private Function LShift(lValue, iShiftBits)     If iShiftBits = 0 Then         LShift = lValue         Exit Function     ElseIf iShiftBits = 31 Then         If lValue And 1 Then             LShift = &H80000000         Else             LShift = 0         End If         Exit Function     ElseIf iShiftBits < 0 Or iShiftBits > 31 Then         Err.Raise 6     End If

    If (lValue And m_l2Power(31 - iShiftBits)) Then         LShift = ((lValue And m_lOnBits(31 - (iShiftBits + 1)))  m_l2Power(iShiftBits)) Or &H80000000     Else         LShift = ((lValue And m_lOnBits(31 - iShiftBits))  m_l2Power(iShiftBits))     End If End Function

Private Function RShift(lValue, iShiftBits)     If iShiftBits = 0 Then         RShift = lValue         Exit Function     ElseIf iShiftBits = 31 Then         If lValue And &H80000000 Then             RShift = 1         Else             RShift = 0         End If         Exit Function     ElseIf iShiftBits < 0 Or iShiftBits > 31 Then         Err.Raise 6     End If          RShift = (lValue And &H7FFFFFFE) &nbsp;m_l2Power(iShiftBits)

    If (lValue And &H80000000) Then         RShift = (RShift Or (&H40000000 &nbsp;m_l2Power(iShiftBits - 1)))     End If End Function

另外,在此基础上再添加两个位运算函数:循环左移和无符号数的加法运算。

Private Function RotateLeft(lValue, iShiftBits)
    RotateLeft = LShift(lValue, iShiftBits) Or RShift(lValue, (32 - iShiftBits))
End Function

Private Function AddUnsigned(lX, lY)     Dim lX4     Dim lY4     Dim lX8     Dim lY8     Dim lResult       lX8 = lX And &H80000000     lY8 = lY And &H80000000     lX4 = lX And &H40000000     lY4 = lY And &H40000000       lResult = (lX And &H3FFFFFFF) + (lY And &H3FFFFFFF)       If lX4 And lY4 Then         lResult = lResult Xor &H80000000 Xor lX8 Xor lY8     ElseIf lX4 Or lY4 Then         If lResult And &H40000000 Then             lResult = lResult Xor &HC0000000 Xor lX8 Xor lY8         Else             lResult = lResult Xor &H40000000 Xor lX8 Xor lY8         End If     Else         lResult = lResult Xor lX8 Xor lY8     End If       AddUnsigned = lResult End Function