如何在Python中获得与PHP adler32哈希相同的结果?

4
我需要用 Python 生成与 PHP 相同的 adler32 哈希值,但是标准实现不同。有什么想法吗?
$ php -r 'print hash("adler32", "bla") . "\n";'
02620130

$ python -c 'import zlib; print zlib.adler32("bla");'
39977264

我使用的是PHP 5.5.9和Python 2.7.6。

目前我已经采取了以下措施:

def php_adler32(string):
    phpcode = """print hash("adler32", "%s");""" % string
    try:
        rv = subprocess.check_output(['php','-r',phpcode], shell=False)
    except subprocess.CalledProcessError as e:
        raise RuntimeError("Could not compute adler32 through php: %s" % e)
    return rv

但我担心这段代码最终会被发布在dailywtf.com上。

2个回答

1

简短回答,Python 给出的结果是十进制的,而 PHP 给出的结果是十六进制的。因此可以这样转换:

php -r 'print hexdec(hash("adler32", "bla")) . "\n";'

简短回答

应该给你一个与Python一致的结果。

详细回答

Adler 32滚动哈希由A值和B值组成。A值从1开始,加上字符模65521的值。B值从0开始,加上当前A值模65521的值,因此对于bla,我们有:

Character Decimal Adler_A Adler_B
                        1       0
      'b'      98      99      99
      'l'     108      207    306
      'a'      97      304    610

因此,整个字符串的最终adler32 A和B值分别为Adler_A = 304Adler_B = 610,当它们转换为大端字节序时,为Adler_A = 0130Adler_B = 0262。因此,您可以看到PHP的哈希函数提供给您的是Adler_B后跟Adler_A的大端表示01300262。将此十六进制值转换为十进制得到39977264,这就是你从python中获取的结果。


谢谢!供以后参考,这是 PHP 的等效代码:"%08d" % int(hex(adler32('bla'))[2:] - Willem

1

从我的观察来看,我认为PHP实现返回了错误的值。( https://github.com/Sembiance/mhash/issues/6 )

当使用PHP使用的旧版mhash库进行测试时(现已被hash取代),我们可以看到与当前hash库相同的结果。

define('MOD_ADLER', 65521);
// Wikipedia Implimentation for testing.
function adler32($data) {
    $a = 1; 
    $b = 0; 
    $len = strlen($data);
    for ($index = 0; $index < $len; ++$index) {
        $a = ($a + $data[$index]) % MOD_ADLER;
        $b = ($b + $a) % MOD_ADLER;
    }
    return ($b << 16) | $a;
}
echo "programed version: " . adler32("bla") . "<br>";
echo "php version: " . hash("adler32", "bla") . "<br>";
echo "mhash version: " .bin2hex(mhash(MHASH_ADLER32, "bla"));

最终结果变成了这样:
programed version: 196609 (I'm not quite sure why this occured to be honest)
php version: 02620130
mhash version: 02620130

我们可以看到,PHP的哈希和混合版本产生了相同的结果,尽管mhash函数返回一个十六进制数字。
就输出而言,zlib Python 的结果将证明是最可靠的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接