我定义了以下结构(名称已匿名,但数据类型正确):
Public Type ExampleDataItem
Limit As Integer ' could be any value 0-999
Status As Integer ' could be any value 0-2
ValidUntil As Date ' always a valid date
End Type
Public Type ExampleData
Name As String ' could be 5-20 chars long
ValidOn As Date ' could be valid date or 1899-12-30 representing "null"
Salt As Integer ' random value 42-32767
Items(0 To 13) As ExampleDataItem
End Type
我想为ExampleData
实例生成32位哈希码。最小化哈希冲突很重要,性能和数据顺序并不重要。
到目前为止,我已经得到(用伪代码):
Long
值。Long
值一起异或。我无法真正发布我的代码,因为它在很大程度上依赖于实用程序类来进行序列化,但是如果有人想看到它,无论我将如何发布它。
这可以吗,或者有人可以建议一种更好的方法吗?
编辑:
此代码用于实现软件许可系统的一部分。哈希的目的是确认最终用户输入的数据是否等于技术支持人员输入的数据。因此,哈希必须:
[散列对于查找,唯一性测试或将ExampleData
实例存储在任何类型的集合中都是不需要的,而仅出于上述目的。
Public Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Public Type GUID2 '15 BYTES TOTAL
Data1(14) As Byte
End Type
Public Declare Function CoCreateGuid Lib "OLE32.DLL" (pGuid As GUID) As Long
Public Function GetGUID() As String
Dim VBRIG_PROC_ID_STRING As String
VBRIG_PROC_ID_STRING = "GetGUID()"
Dim lResult As Long
Dim lguid As GUID
Dim MyguidString As String
Dim MyGuidString1 As String
Dim MyGuidString2 As String
Dim MyGuidString3 As String
Dim DataLen As Integer
Dim StringLen As Integer
Dim i As Integer
On Error GoTo error_olemsg
lResult = CoCreateGuid(lguid)
If lResult = 0 Then
MyGuidString1 = Hex$(lguid.Data1)
StringLen = Len(MyGuidString1)
DataLen = Len(lguid.Data1)
MyGuidString1 = LeadingZeros(2 * DataLen, StringLen) & MyGuidString1
'First 4 bytes (8 hex digits)
MyGuidString2 = Hex$(lguid.Data2)
StringLen = Len(MyGuidString2)
DataLen = Len(lguid.Data2)
MyGuidString2 = LeadingZeros(2 * DataLen, StringLen) & Trim$(MyGuidString2)
'Next 2 bytes (4 hex digits)
MyGuidString3 = Hex$(lguid.Data3)
StringLen = Len(MyGuidString3)
DataLen = Len(lguid.Data3)
MyGuidString3 = LeadingZeros(2 * DataLen, StringLen) & Trim$(MyGuidString3)
'Next 2 bytes (4 hex digits)
GetGUID = MyGuidString1 & MyGuidString2 & MyGuidString3
For i = 0 To 7
MyguidString = MyguidString & Format$(Hex$(lguid.Data4(i)), "00")
Next i
'MyGuidString contains last 8 bytes of Guid (16 hex digits)
GetGUID = GetGUID & MyguidString
Else
GetGUID = "00000000" ' return zeros if function unsuccessful
End If
Exit Function
error_olemsg:
GetGUID = "00000000"
Exit Function
End Function
Public Function LeadingZeros(ExpectedLen As Integer, ActualLen As Integer) As String
LeadingZeros = String$(ExpectedLen - ActualLen, "0")
End Function
EDIT:现在,已经对问题进行了编辑,以澄清目标是检测键入错误,而不是最大程度地减少完全不同的值之间的冲突。在这种情况下,Dan F's answer是最好的恕我直言,不是我下面提供的产品(虽然很棒)。
hash(CStr(Salt) + Name + CStr(ValidOn) + Anyotherstrings
不需要特别进行序列化为字节数组和XORing值的过程。以这种方式对值进行异或运算,更有可能在您不希望它们发生的地方产生哈希冲突。编辑:我想我现在明白了。您是通过将数据异或创建自己的哈希值?不幸的是很可能发生碰撞。我知道VB6不包含任何哈希算法,因此您最好导入并使用Phil Fresle's SHA256 implementation之类的东西。