如何将摘要的前 n 位转换为整数?
How to turn the first n bits of a digest into a integer?
我正在使用 Python 3,尝试从 python 中的摘要中获取整数。不过,我只对摘要的前 n 位感兴趣。
我现在有的是:
n = 3
int(hashlib.sha1(b'test').digest()[0:n])
然而,这会导致 ValueError: invalid literal for int() with base 10: b'\xa9J'
错误。
谢谢。
Py3的解决办法是用int.from_bytes
把bytes
转成int
,然后把你不关心的部分移掉:
def bitsof(bt, nbits):
# Directly convert enough bytes to an int to ensure you have at least as many bits
# as needed, but no more
neededbytes = (nbits+7)//8
if neededbytes > len(bt):
raise ValueError("Require {} bytes, received {}".format(neededbytes, len(bt)))
i = int.from_bytes(bt[:neededbytes], 'big')
# If there were a non-byte aligned number of bits requested,
# shift off the excess from the right (which came from the last byte processed)
if nbits % 8:
i >>= 8 - nbits % 8
return i
使用示例:
>>> bitsof(hashlib.sha1(b'test').digest(), 3)
5 # The leftmost bits of the a nibble that begins the hash
在 Python 2 上,该函数几乎可以按原样使用,除了添加一个 binascii
导入,并将转换从 bytes
更改为 int
到效率稍低的两步转换(从 str
到十六进制表示,然后使用 int
和 base
为 16 来解析它):
i = int(binascii.hexlify(bt[:neededbytes]), 16)
其他一切都按原样工作(甚至 //
运算符也按预期工作;Python 2 的 /
运算符与 Py 3 不同,但 //
工作相同在两者上)。
我正在使用 Python 3,尝试从 python 中的摘要中获取整数。不过,我只对摘要的前 n 位感兴趣。
我现在有的是:
n = 3
int(hashlib.sha1(b'test').digest()[0:n])
然而,这会导致 ValueError: invalid literal for int() with base 10: b'\xa9J'
错误。
谢谢。
Py3的解决办法是用int.from_bytes
把bytes
转成int
,然后把你不关心的部分移掉:
def bitsof(bt, nbits):
# Directly convert enough bytes to an int to ensure you have at least as many bits
# as needed, but no more
neededbytes = (nbits+7)//8
if neededbytes > len(bt):
raise ValueError("Require {} bytes, received {}".format(neededbytes, len(bt)))
i = int.from_bytes(bt[:neededbytes], 'big')
# If there were a non-byte aligned number of bits requested,
# shift off the excess from the right (which came from the last byte processed)
if nbits % 8:
i >>= 8 - nbits % 8
return i
使用示例:
>>> bitsof(hashlib.sha1(b'test').digest(), 3)
5 # The leftmost bits of the a nibble that begins the hash
在 Python 2 上,该函数几乎可以按原样使用,除了添加一个 binascii
导入,并将转换从 bytes
更改为 int
到效率稍低的两步转换(从 str
到十六进制表示,然后使用 int
和 base
为 16 来解析它):
i = int(binascii.hexlify(bt[:neededbytes]), 16)
其他一切都按原样工作(甚至 //
运算符也按预期工作;Python 2 的 /
运算符与 Py 3 不同,但 //
工作相同在两者上)。