[英]How to implement murmurhash3 in VBNET
我正在嘗試在vb.net中實現murmurhash3,並嘗試從此C#實現進行轉換
C#函數的第一部分
public static SqlInt32 MurmurHash3(SqlBinary data)
{
const UInt32 c1 = 0xcc9e2d51;
const UInt32 c2 = 0x1b873593;
int curLength = data.Length; /* Current position in byte array */
int length = curLength; /* the const length we need to fix tail */
UInt32 h1 = seed;
UInt32 k1 = 0;
/* body, eat stream a 32-bit int at a time */
Int32 currentIndex = 0;
while (curLength >= 4)
{
/* Get four bytes from the input into an UInt32 */
k1 = (UInt32)(data[currentIndex++]
| data[currentIndex++] << 8
| data[currentIndex++] << 16
| data[currentIndex++] << 24);
/* bitmagic hash */
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
curLength -= 4;
}
在VB.net中也是如此:
Public Shared Function MurmurHash3(data As Byte()) As Int32
Const c1 As UInt32 = &HCC9E2D51UI
Const c2 As UInt32 = &H1B873593
Dim curLength As Integer = data.Length
' Current position in byte array
Dim length As Integer = curLength
' the const length we need to fix tail
Dim h1 As UInt32 = seed
Dim k1 As UInt32 = 0
' body, eat stream a 32-bit int at a time
Dim dBytes As Byte()
Dim currentIndex As Int32 = 0
While curLength >= 4
' Get four bytes from the input into an UInt32
dBytes = New Byte() {data(currentIndex), data(currentIndex + 1), data(currentIndex + 2), data(currentIndex + 3)}
k1 = BitConverter.ToUInt32(dBytes, 0)
currentIndex += 4
' bitmagic hash
k1 *= c1
k1 = rotl32(k1, 15)
k1 *= c2
h1 = h1 Xor k1
h1 = rotl32(h1, 13)
h1 = h1 * 5 + &HE6546B64UI
curLength -= 4
End While
Private Shared Function rotl32(x As UInt32, r As Byte) As UInt32
Return (x << r) Or (x >> (32 - r))
End Function
k1 * = c1引發錯誤算術運算導致溢出。
有什么建議應如何實施? 我不知道如何處理從輸入到UInt32部分的輸入中的四個字節,這是問題所在還是與其他問題有關,因為C#和VB之間的按位運算存在一些差異。
供參考的Java實現也存在https://github.com/yonik/java_util/blob/master/src/util/hash/MurmurHash3.java
首先,我首先將32位k1
轉換為64位變體,例如:
k1_64 = CType(k1, UInt64)
對於模32位計算,請執行
k1_64 = (k1_64 * c1) And &HFFFFFFFFUI
最后,重鑄回32位
k1 = CType(k1_64 And $HFFFFFFFFUI, UInt32)
為了提高性能,您可能需要考慮將BitConverter.ToUInt
調用替換為其他內容。
編輯:這是一個沒有附加變量的簡單版本(但帶有“幫助程序常量”)
Const LOW_32 as UInt32 = &HFFFFFFFFUI
' ... intervening code ...
k1 = (1L * k1 * c1) And LOW_32
' ... later on ...
h1 = (h1 * 5L + &HE6546B64UL) And LOW_32
1L
強制在paren中將計算結果設為Long(Int64)。 And LOW_32
將非零位的數目減少到32,然后將整體結果自動轉換為UInt32。 在h1
線上h1
發生類似的情況。
參考: http : //www.undermyhat.org/blog/2009/08/secrets-and-lies-of-type-suffixes-in-c-and-vb-net/ (向下滾動至“常量的秘密”部分並輸入后綴”)
不幸的是,是否有可能在VB.NET中執行未經檢查的{}? 您可以使用try / catch阻止,如果溢出則手動進行移位。 請注意,在其中放置錯誤處理程序會減慢哈希計算的速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.