Хеширование не-ascii строки Python - PullRequest
2 голосов
/ 22 октября 2011

Я пытаюсь извлечь некоторую строку из файла, используя python re, затем MD5ing эту строку, используя что-то вроде:

    #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' 

1 Ответ

4 голосов
/ 22 октября 2011

Строка в первом случае - это именно то, что вы видели напечатанным:

>>> 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
...