【问题标题】:Hashing non-ascii Python string散列非 ascii Python 字符串
【发布时间】:2011-10-22 02:48:17
【问题描述】:

我正在尝试使用 python re 从文件中提取一些字符串,然后使用 MD5 对这个字符串进行 类似:

    #MD5er.py
    salt = extract_salt(file_foo)
    print 'salt: %s' % salt
    from md5 import md5
    print 'hash: %s' % md5(salt).hexdigest()

$python MD5er

    salt: \0001\072\206\277\354\107\134\061\361\076\150\047\010\124\200\315\100
    hash: ce24166858853dfb12a86d7d602b0638

但是,像这样使用 iPython:

    In [40]: salt = '\0001\072\206\277\354\107\134\061\361\076\150\047\010\124\200\315\100'

    In [41]: salt
    Out[41]: "\x001:\x86\xbf\xecG\\1\xf1>h'\x08T\x80\xcd@"

    In [42]: print salt
    1:���G\1�>hT��@

    In [43]: from md5 import md5

    In [44]: md5(salt).hexdigest()
    Out[44]: 'ebae47a953591f7448ff7079837fb534'

任何线索为什么 MD5 在 2 个场景中不同? 为什么在 ipython 中当我输入变量名时,它以与原始字符串不同的格式出现,而 print() 输出是第三种格式!?

提示:

    In [53]: import sys
    In [54]: sys.getdefaultencoding()
    Out[54]: 'ascii' 

【问题讨论】:

  • 文件中真的有反斜杠吗?

标签: python unicode hash md5 ascii


【解决方案1】:

第一种情况下的字符串正是你看到的打印内容:

>>> salt = '\\0001\\072\\206\\277\\354\\107\\134\\061\\361\\076\\150\\047\\010\\
124\\200\\315\\100'
>>> md5(salt).hexdigest()
'ce24166858853dfb12a86d7d602b0638'

请注意我如何转义反斜杠以防止将数字解释为八进制字节值。

第一种情况下的字符串正是你看到的打印内容:

>>> salt = '\\0001\\072\\206\\277\\354\\107\\134\\061\\361\\076\\150\\047\\010\\
124\\200\\315\\100'
>>> md5(salt).hexdigest()
'ce24166858853dfb12a86d7d602b0638'

请注意我如何转义反斜杠以防止将数字解释为八进制字节值。

编辑:

假设你想从这个列表中的八进制值创建一个字节字符串:

data = ['\\0001', '\\072', '\\206', '\\277', '\\354', '\\107', '\\134', 
        '\\061', '\\361', '\\076', '\\150', '\\047', '\\010', '\\124', 
        '\\200', '\\315', '\\100']

你可以转换成整数,然后加入字符,但这与你在 IPython 中得到的不同。第一个值是 4 位而不是 3。应该将其视为 '\0' 后跟 ASCII '1',还是应视为 '\1'?以下是后者:

salt = ''.join(chr(int(d[1:], 8)) for d in data)
print repr(salt)
print md5(salt).hexdigest()

输出:

"\x01:\x86\xbf\xecG\\1\xf1>h'\x08T\x80\xcd@"
d2092426d1bd5bec1579c8b7ed9c73c2

【讨论】:

  • 感谢 eryksu,我从中构造字符串的列表如下:l = ['\\0001', '\\072', '\\206', '\\277', ' \\354', '\\107', '\\134', '\\061', '\\361', '\\076', '\\150', '\\047', '\\ 010', '\\124', '\\200', '\\315', '\\100'] 我需要删除转义字符'\',并将所有元素连接到一个字符串以与原始字符串相同我贴的一张。所以我尝试了: >>>l2 = [element[1:] for element in l] >>>n = '' >>>for el in l2: n += el 但我得到了: In [117]: n Out [117]: '0001072206277354107134061361076150047010124200315100' wz 不同的 MD5
  • 对于“\\0001”,是的,我需要“\\000”,然后在转换后注入“1”。谢谢 eryksun,它工作:)
猜你喜欢
  • 1970-01-01
  • 2013-06-20
  • 2017-04-13
  • 1970-01-01
  • 2013-03-22
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多