pickle.dumps在python2,3中的兼容性

pickle.dumps在python2,3中的兼容性,python,pickle,hashlib,Python,Pickle,Hashlib,我正在尝试编写一个函数来对任何python对象进行md5哈希。在python2和python3中,它返回相同的md5值 我知道python3中的pickle.dumps返回字节,而python2中的pickle.dumps返回str。正如您所见,下面的代码现在为我提供了相同的字符串: print( [ pickle.dumps( obj, protocol = 2 ) ] ) # in python2 print( [ str( pickle.dumps( obj, protoco

我正在尝试编写一个函数来对任何python对象进行md5哈希。在python2和python3中,它返回相同的md5值

我知道python3中的pickle.dumps返回字节,而python2中的pickle.dumps返回str。正如您所见,下面的代码现在为我提供了相同的字符串:

print( [      pickle.dumps( obj, protocol = 2 )   ] ) # in python2
print( [ str( pickle.dumps( obj, protocol = 2 ) ) ] ) # in python3
两者都给了我:

['\x80\x02]q\x00(U\x011q\x01K\x02U\x013q\x02K\x04e.']
但问题是,在python3中:

hashlib.md5.update( some_string )
必须进行编码。如果我在python3中对字符串进行编码,那么它不会给我与python2中相同的md5值。谁能给我一个解决方案?谢谢你们

这是我的密码:

from __future__ import print_function
import hashlib
import pickle
import sys

is_py2 = (sys.version_info[0] == 2)

obj = ['1',2,'3',4]
m = hashlib.md5()

if is_py2:                                                    # if it's python2
    print(    [      pickle.dumps( obj, protocol = 2 ) ] )
    m.update(        pickle.dumps( obj, protocol = 2 )   )
else:                                                         # if it's python3
    print(    [ str( pickle.dumps( obj, protocol = 2 ) ) ] )
    m.update(        pickle.dumps( obj, protocol = 2 ).encode( "utf-8" ) ) # I wish I could don not encode

print( m.hexdigest() )
1 pickle.dumps将返回一个字节字符串,因此您的打印错误

2如果由于某种原因,unicode字符串中包含此类内容,则不能使用默认的多字节编解码器utf-8

foo = '\x80\x02]q\x00(U\x011q\x01K\x02U\x013q\x02K\x04e.'.encode('latin-1')
latin-1将有一个1对1的映射,因此您将得到正确的字节


PS:你为什么要在打印中使用列表?也许您正在寻找printrepr…

有一个单行程序可以进行2x和3x编码,您可以进行任何编码

>>> hashlib.new(algorithm, repr(object).encode()).hexdigest()
请参阅:有关变量名的完整上下文…请参阅文件的其余部分,以了解更多关于编码、序列化等的抽象。所有这些都在Python2.x和3.x中工作

我知道您希望Python2.x和3.x返回相同的散列。隐马尔可夫模型。。。我认为那不管用。如果它有可能在2.x中返回与3.x中相同的md5编码,那么您可能必须首先使用repr或pickle protocol 2或其他方法

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import klepto
>>> klepto.crypto.hash(klepto.crypto.pickle(object), algorithm='md5')
'ee16782749cb00e4b66922df545877f0'
所以,pickle和md5似乎不起作用,通常也不应该起作用,因为一些对象在2.x和3.x之间发生了变化,例如,对象是一种类型,现在它是一个类。这也意味着repr或其他类似的东西一般也不能作为编码器工作

Python 3.3.5 (default, Mar 10 2014, 21:37:38) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import klepto
>>> klepto.crypto.hash(klepto.crypto.pickle(object), algorithm='md5')
'35eb4c374cafe09c8ac01661701b6b6e'

也许klepto的其他编码器中有一个可以为您工作。

请给我代码,使对象的md5值在py2,3中都相同,好吗?