簡體   English   中英

如何在PHP 7.2中生成64位Murmur哈希v2?

[英]How to generate a 64bit Murmur hash v2 in PHP 7.2?

我有一個MySQL數據庫,該數據庫具有一些Permura UDF生成的Murmur2散列(作為無符號的64位整數),該散列是隨MySQL數據庫的Percona鏈一起提供的,可在這里https://github.com/percona/build-test/ Blob /主控/插件/percona-udf/murmur_udf.cc

我的問題是,現在我需要在PHP端生成這些相同的哈希值,但是我似乎無法找到或調整任何現有的東西來為相同的輸入工作/輸出相同的輸出。

我嘗試過的事情:

  1. 將Percona UDF中的C ++函數復制到此PHP擴展的派生版本中,該版本最初產生32位int哈希值https://github.com/StirlingMarketingGroup/php_murmurhash 這幾乎可以正常工作,就像在編譯時一樣,但是當我在PHP中執行該功能時,apache服務器因段錯誤而崩潰,並且我對C ++和PHP擴展尚不熟悉,無法對其進行調試

段錯誤是由我運行此功能引起的

var_dump(murmurhash('Hello World'));

當我下載https://github.com/kibae/php_murmurhash (原始的,32位,產生哈希的擴展名)並按照說明進行操作時,該方法正常運行,但是一旦我替換了該功能(僅在MurmurHash2.cpp文件中將其編輯為https) http://github.com/StirlingMarketingGroup/php_murmurhash/blob/master/MurmurHash2.cpp ),同一函數調用會使PHP腳本崩潰。

  1. 嘗試將Percona UDF C ++函數移植到PHP。 我不太確定我的PHP函數在嘗試解決指針增加時是否100%准確,但我懷疑更多,因此我在PHP版本中獲得完全不同的輸出的原因與PHP不支持無符號整數有關。

這是我作為Percona C ++函數的端口編寫的PHP函數

function murmurhash2(string $s) : int {
    $len = strlen($s);
    $seed = 0;

    $m = 0x5bd1e995;
    $r = 24;

    $h1 = $seed ^ $len;
    $h2 = 0;

    $i = 0;

    while ($len >= 8) {
        $k1 = ord($s[$i++]);
        $k1 *= $m; $k1 ^= $k1 >> $r; $k1 *= $m;
        $h1 *= $m; $h1 ^= $k1;
        $len -= 4;

        $k2 = ord($s[$i++]);
        $k2 *= $m; $k2 ^= $k2 >> $r; $k2 *= $m;
        $h2 *= $m; $h2 ^= $k2;
        $len -= 4;
    }

    if ($len >= 4) {
        $k1 = ord($s[$i++]);
        $k1 *= $m; $k1 ^= $k1 >> $r; $k1 *= $m;
        $h1 *= $m; $h1 ^= $k1;
        $len -= 4;
    }

    switch ($len) {
        case 3: $h2 ^= ord($s[2]) << 16;
        case 2: $h2 ^= ord($s[1]) << 8;
        case 1: $h2 ^= ord($s[0]);
                $h2 *= $m;
    };

    $h1 ^= $h2 >> 18; $h1 *= $m;
    $h2 ^= $h1 >> 22; $h2 *= $m;
    $h1 ^= $h2 >> 17; $h1 *= $m;

    $h = $h1;

    $h = ($h << 32) | $h2;
    return $h;
}

在MySQL中我得到這個

select murmur_hash('Hello World'), cast(murmur_hash('Hello World')as unsigned), CONV(cast(murmur_hash('Hello World')as unsigned), 10, 16);
-- -8846466548632298438 9600277525077253178 853B098B6B655C3A

在PHP中我得到

var_dump(murmurhash2('Hello World'));
// int(5969224437940092928)

因此,查看MySQL和PHP結果,有符號和無符號都不匹配我的PHP輸出。

我的前兩種方法是否可以解決某些問題,或者可以替代使用一種已經有效的方法?

我已經通過將Percona哈希函數直接移植到PHP擴展MySQL來解決了這個問題。

安裝和使用說明發布在這里https://github.com/StirlingMarketingGroup/php-murmur-hash


輸出示例

在MySQL中,Percona擴展的用法類似於

select`murmur_hash`('Yeet')
-- -7850704420789372250

而在PHP中

php -r 'echo murmur_hash("Yeet");'
// -7850704420789372250

請注意,兩種環境都將它們視為有符號整數,您可以在MySQL中通過使用cast(`murmur_hash`('Yeet')as unsigned) ,但PHP不支持無符號整數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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