gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 17:16:54 29 4
gpt4 key购买 nike

我有一个 MySQL 数据库,其中包含一些 Murmur2 哈希值(作为无符号 64 位整数),这些哈希值是使用 Percona UDF 生成的,该 UDF 随 MySQL 数据库的 Percona 链一起提供,可在此处找到 https://github.com/percona/build-test/blob/master/plugin/percona-udf/murmur_udf.cc

我的问题是,现在我需要在 PHP 端生成这些相同的哈希值,但我似乎无法找到或调整现有的任何内容来为相同的输入工作/输出相同的输出。

我尝试过的事情:

  1. 将 Percona UDF 中的 C++ 函数复制到该 PHP 扩展的 fork 版本中,该扩展最初生成 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://github.com/StirlingMarketingGroup/php_murmurhash/blob/master/MurmurHash2.cpp ),相同的函数调用就会使 PHP 脚本崩溃。

  • 尝试将 Percona UDF C++ 函数移植到 PHP。我不太确定我的 PHP 函数在尝试考虑指针递增时是否 100% 准确,但我怀疑更多,因此我在 PHP 版本中获得完全不同的输出的原因与 PHP 不支持无符号整数有关。
  • 这是我编写的 PHP 函数,作为 Percona C++ 函数的移植

    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 不会支持无符号整数。

    关于php - 如何在 PHP 7.2 中生成 64 位 Murmur 哈希 v2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51525616/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com