Python3 и hmac. Как обрабатывать строку, не являющуюся двоичной
У меня был скрипт в Python2, который отлично работал.
def _generate_signature(data):
return hmac.new('key', data, hashlib.sha256).hexdigest()
Где данные были результатом json.dumps
.
Теперь, если я попытаюсь запустить такой же код в Python 3, я получаю следующее:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.4/hmac.py", line 42, in __init__
raise TypeError("key: expected bytes or bytearray, but got %r" %type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'
Если я попробую что-то вроде преобразования ключа в байты следующим образом:
bytes('key')
я получил
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
Я все еще пытаюсь понять кодировки в Python 3.
Ответы
Ответ 1
Вы можете использовать байты b'key'
: b'key'
def _generate_signature(data):
return hmac.new(b'key', data, hashlib.sha256).hexdigest()
Кроме того, убедитесь, что data
также являются байтами. Например, если он читается из файла, вам нужно использовать binary
режим (rb
) при открытии файла.
Ответ 2
Чтобы не воскресить старый вопрос, но я хотел добавить что-то, чего я чувствую, отсутствует в этом ответе, к которому у меня возникли проблемы с поиском подходящего объяснения/примера где-либо еще:
OP Aquiles Carattino был довольно близок к своей попытке преобразовать строку в байты, но отсутствовал второй аргумент - кодировка строки, которая должна быть преобразована в байты.
Если кто-то хочет преобразовать строку в байты с помощью других средств, кроме статического присваивания (например, чтение из файла конфигурации или БД), должно работать следующее:
import hmac, hashlib
def _generate_signature(data):
key = 'key' # Defined as a simple string.
key_bytes= bytes(key , 'latin-1')
data_bytes = bytes(data, 'latin-1') # Assumes 'data' is also a string.
return hmac.new(key_bytes, data_bytes , hashlib.sha256).hexdigest()
print(
_generate_signature('this is my string of data')
)
Ответ 3
попробуйте
codecs.encode()
который можно использовать как в python2.7.12, так и в 3.5.2
import hashlib
import codecs
import hmac
a = "aaaaaaa"
b = "bbbbbbb"
hmac.new(codecs.encode(a), msg=codecs.encode(b), digestmod=hashlib.sha256).hexdigest()