hashlib.md5() TypeError: Unicode-объекты должны быть закодированы перед хешированием

Я новичок в кодировании и столкнулся с проблемой, пытающейся закодировать строку.

>>> import hashlib
>>> a = hashlib.md5()
>>> a.update('hi')
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    a.update('hi')
TypeError: Unicode-objects must be encoded before hashing
>>> a.digest()
b'\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\t\x98\xec\xf8B~'

Является ли (а) теперь считаться кодированным?

Второй вопрос: когда я запускаю тот же код выше в скрипте, я получаю эту ошибку:

import hashlib
a = hashlib.md5()
a.update('hi')
a.digest()

Traceback (последний последний вызов): Файл "C: /Users/User/Desktop/Logger/Encoding practice.py", строка 3, в a.update('hi') TypeError: объекты Unicode должны быть закодированы перед хэшированием

Почему код работает в оболочке, а не в скрипте? Я работаю с Windows и Python 3.4

Благодарю.

Ответ 1

Поскольку вы кодируете простые строки, я выводю, что вы используете Python 3, где все строки являются объектами unicode, у вас есть два варианта:

  1. Предоставьте кодировку для строк, например: "Nobody inspects".encode('utf-8')
  2. Используйте двоичные строки, как показано в руководствах:

    m.update(b"Nobody inspects")
    m.update(b" the spammish repetition")
    

Причиной различного поведения в скрипте для оболочки является то, что сценарий останавливается на ошибке, тогда как в оболочке последняя строка представляет собой отдельную команду, но все еще не делает то, что вы хотите, из-за предыдущей ошибки.

Ответ 2

Решение, которое я нашел, - это просто закодировать данные прямо в строке, где вы его хешируете:

hashlib.sha256("a".encode('utf-8')).hexdigest()

Это сработало для меня, надеюсь, это поможет!

Ответ 3

В разных версиях Python отличается, я использую Python 2.7, так же, как вы пишете, он работает хорошо.

hashlib.md5 (данные), тип данных должен быть "байтами". То есть мы должны поместить тип данных в байты перед хэшами.

Требования перед преобразованием хеш-кода, поскольку одна и та же строка имеет разные значения в разных системах кодирования (utf8\gbk.....), чтобы гарантировать, что не должно быть двусмысленности, должно быть доминирующим преобразованием.

Ответ 4

Он не работает в REPL. Он ничего не хэшировал, так как вы передали ему ничего не действительного для хэша. Сначала попробуйте кодировать.

3>> hashlib.md5().digest()
b'\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\t\x98\xec\xf8B~'
3>> a = hashlib.md5()
3>> a.update('hi'.encode('utf-8'))
3>> a.digest()
b'I\xf6\x8a\\\x84\x93\xec,\x0b\xf4\x89\x82\x1c!\xfc;'

Ответ 5

Для Python3 работает следующее.

secretKey = b"secret key that you get from Coginito -> User Pool -> General Settings -> App Clients-->Click on Show more details -> App client secret"
        clientId = "Coginito -> User Pool -> General Settings -> App Clients-->App client id"
        digest = hmac.new(secretKey,
                  msg=(user_name + clientId).encode('utf-8'),
                  digestmod=hashlib.sha256
                 ).digest()
        signature = base64.b64encode(digest).decode()

Имя пользователя user_name в приведенном выше идентично имени пользователя, которого вы хотите зарегистрировать в Cognito.