我想把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将不再更新。
如何以不同的方式修复该算法或实现此算法?
发布于 2014-03-13 20:04:07
我想问一下,用这种方式散列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发布于 2014-03-13 16:59:17
我找到了一个解决办法,使用货币和自己做溢出运算(结果是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获得的解决方案几乎是我的解决方案的两倍。
https://stackoverflow.com/questions/22384451
复制相似问题