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

如何在Python中获得相同的PHP adler32哈希?,php,python,hash,Php,Python,Hash,我需要生成相同的adler32哈希,它是由PHP生成的,但使用Python。不幸的是,标准实现不同。有什么想法吗 $ php -r 'print hash("adler32", "bla") . "\n";' 02620130 $ python -c 'import zlib; print zlib.adler32("bla");' 39977264 (Am使用PHP5.5.9和Python 2.7.6) 目前我已经求助于 def php_adler32(string): phpco

我需要生成相同的adler32哈希,它是由PHP生成的,但使用Python。不幸的是,标准实现不同。有什么想法吗

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

$ python -c 'import zlib; print zlib.adler32("bla");'
39977264
(Am使用PHP5.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上看到这段代码。

环顾四周,我相信PHP实现返回了不正确的值。()

当使用PHP使用的较旧的mhash库(现在已被散列弃用)进行测试时,我们可以看到与当前散列库相同的结果

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"));
我们可以看到PHP(hash)和mash版本产生相同的结果,尽管mhash函数返回十六进制数


zlib-python结果在输出方面是最可靠的。

简而言之,pyton给出的结果是十进制的,PHP给出的结果是十六进制的。因此,我想:

php -r 'print hexdec(hash("adler32", "bla")) . "\n";'
应该给出一个与python一致的结果

更长的答案

adler 32滚动散列由A和B值组成。A值从1开始,加上字符模65521的值。B值从零开始,加上当前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=304
Adler_B=610
,当转换为大端十六进制时是
Adler_A=0130
Adler_B=0262
。所以你可以看到PHP的散列给你一个Adler_B的大端表示,后面跟着Adler_a,
01300262
。将此十六进制值转换为十进制值将得到
39977264
,这是您从python获得的。

谢谢!为了将来的参考,这相当于PHP:
%08d”%int(十六进制(adler32('bla'))[2://code>
Character Decimal Adler_A Adler_B
                        1       0
      'b'      98      99      99
      'l'     108      207    306
      'a'      97      304    610