不是来自已知摘要,而是来自已知状态。您可以使用纯python
MD5实现并保存其状态。这是使用来自PyPy的_md5.py的示例:
import _md5def md5_getstate(md): return (md.A, md.B, md.C, md.D, md.count + [], md.input + [], md.length)def md5_continue(state): md = _md5.new() (md.A, md.B, md.C, md.D, md.count, md.input, md.length) = state return mdm1 = _md5.new()m1.update("hello, ")state = md5_getstate(m1)m2 = md5_continue(state)m2.update("world!")print m2.hexdigest()m = _md5.new()m.update("hello, world!")print m.hexdigest()
如e.dan所述,您还可以使用几乎所有校验和算法(CRC,Adler,Fletcher),但是它们不能很好地保护您免受故意的数据修改的影响,而只能防止随机错误。
编辑:当然,您也可以使用ctypes从您引用的线程中以更可移植的方式(没有魔术常数)重新实现序列化方法。我认为这应该与版本/架构无关(在python
2.4-2.7,i386和x86_64上测试):
# based on idea from http://groups.google.com/group/comp.lang.python/msg/b1c5bb87a3ff5e34try: import _md5 as md5except importError: # python 2.4 import md5import ctypesdef md5_getstate(md): if type(md) is not md5.MD5Type: raise TypeError, 'not an MD5Type instance' return ctypes.string_at(id(md) + object.__basicsize__, md5.MD5Type.__basicsize__ - object.__basicsize__)def md5_continue(state): md = md5.new() assert len(state) == md5.MD5Type.__basicsize__ - object.__basicsize__, 'invalid state' ctypes.memmove(id(md) + object.__basicsize__, ctypes.c_char_p(state), len(state)) return mdm1 = md5.new()m1.update("hello, ")state = md5_getstate(m1)m2 = md5_continue(state)m2.update("world!")print m2.hexdigest()m = md5.new()m.update("hello, world!")print m.hexdigest()
它不兼容Python 3,因为它没有_md5 / md5模块。
不幸的是,因为OpenSSL EVP
API不提供任何调用/方法来可靠地序列化EVP_MD_CTX对象,所以hashlib的openssl_md5实现不适合此类黑客。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)