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.のエンコーディングを理解するのにまだ苦労しています。
バイトリテラルを使用できます:b'key'
def _generate_signature(data):
return hmac.new(b'key', data, hashlib.sha256).hexdigest()
それに加えて、data
もバイトであることを確認してください。たとえば、ファイルから読み取る場合、ファイルを開くときにbinary
モード(rb
)を使用する必要があります。
古い質問を復活させるのではなく、私はこの答えに欠けていると感じたものを追加したかったのですが、他の場所の適切な説明/例を見つけるのに苦労しました:
OP Aquiles Carattinoは、文字列をバイトに変換する試みにかなり近かったが、2番目の引数、バイトに変換される文字列のエンコードが欠落していた。
誰かが静的割り当て以外の方法(構成ファイルやDBからの読み取りなど)で文字列をバイトに変換したい場合、次のように動作します。
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')
)