簡體   English   中英

如何在VBNET中實現murmurhash3

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM