尝试使用时间戳和 base64 编码的 json 字符串创建哈希,出现内存错误

问题描述

这个简单的脚本因内存错误而终止,我不知道为什么。

import simplejson as json
import hmac
import hashlib
from time import time
import base64
sso_user={'a':'foo','b':'bar'}
ssoKey=b'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
timestamp = round(time() * 1000)
s=json.dumps(sso_user)
userDataJSONBase64 = base64.b64encode(s.encode())
verificationHash = hmac.new(
    bytes(timestamp)+userDataJSONBase64,ssoKey,hashlib.sha256
).hexdigest()
print(verificationHash)

它在 hmac.new() 上窒息

解决方法

问题在于您使用的 bytes built-in in python3 与在 python2 中的行为不同。在python2.7中,bytesstr的别名。在 python3 中,采用整数的构造函数生成一个 N 0 的数组。由于您传入的是 1,617,219,736,292(2021 年 3 月 31 日)之类的内容,因此您正在初始化一个大小为 1.6 万亿的数组并且内存不足:MemoryError

$ python2
>>> print(bytes.__doc__)
str(object='') -> string

Return a nice string representation of the object.
If the argument is a string,the return value is the same object.
^C
$ python3
>>> print(bytes.__doc__)
bytes(iterable_of_ints) -> bytes
bytes(string,encoding[,errors]) -> bytes
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
bytes(int) -> bytes object of size given by the parameter initialized with null bytes
bytes() -> empty bytes object

Construct an immutable array of bytes from:
  - an iterable yielding integers in range(256)
  - a text string encoded using the specified encoding
  - any object implementing the buffer API.
  - an integer
,

我做了这个更改,似乎解决了这个问题。

verificationHash = hmac.new(
      str(timestamp).encode() + userDataJSONBase64,ssoKey,hashlib.sha256
  ).hexdigest()