VB6如何获得类似C的整数溢出

时间:2014-03-13 16:10:22

标签: hash vb6 integer-overflow

我想将this simple hash algorithm移植到VB6。

我想出了:

Public Function simpleHash(hashString As String) As Long
Dim hash As Long
Dim c As Long
Dim i As Integer

    On Local Error Resume Next

    hash = 5381
    For i = 1 To Len(hashString)
        c = AscW(Mid$(hashString, i, 1))
        hash = hash * 33 + c
    Next i

    simpleHash = hash
End Function

问题是,尽管我的On Error语句抑制了错误6:溢出异常,但如果发生溢出,变量hash不会再更新。

如何解决这个问题或以不同方式实施此算法?

2 个答案:

答案 0 :(得分:3)

我会怀疑以这种方式散列UTF-16LE(" Unicode")是否有意义。将VB字符串转换为UTF-8 然后哈希可能会更有意义。

虽然我无法找到 djb2 的任何测试向量来验证我自己的实现,但它似乎运行得很快:

Private Type CURRENCY_CURRENCY
    Value As Currency
End Type

Private Type CURRENCY_2LONGS
    ValueLo As Long
    ValueHi As Long
End Type

Public Function djb2(ByVal StringToHash As String) As Long
    Dim C2L As CURRENCY_2LONGS
    Dim CC As CURRENCY_CURRENCY
    Dim I As Long

    C2L.ValueLo = 5381
    For I = 1 To Len(StringToHash)
        LSet CC = C2L
        CC.Value = CC.Value * 33@ + CCur(AscW(Mid$(StringToHash, I, 1))) / 10000@
        LSet C2L = CC
        C2L.ValueHi = 0
    Next I

    djb2 = C2L.ValueLo
End Function

答案 1 :(得分:2)

我找到了一个解决方法,使用 Currency 并自己进行溢出数学运算(事实证明VB6 Mod运算符也不能在Currency上运行):

Const pow2_32 As Currency = 2@ ^ 32
Const signed32Max As Currency = 2@ ^ 31 - 1

Public Function simpleHash(hashString As String) As Long
Dim hash As Currency
Dim i As Long

    hash = 5381
    For i = 1 To Len(hashString)
        hash = hash * 33@ + CCur(AscW(Mid$(hashString, i, 1)))
        While hash >= pow2_32
            hash = hash - pow2_32
        Wend
    Next i

    If hash > signed32Max Then
        hash = hash - pow2_32
    End If

    simpleHash = CLng(hash)
End Function

但是,请参阅Bob77's answer以获得几乎是我的解决方案速度的两倍的解决方案。