我正在使用Python 3,尝试从python的摘要中获取一个整数。我只对摘要的前n位感兴趣。
我现在拥有的是:
n = 3
int(hashlib.sha1(b'test').digest()[0:n])
然而,这会导致ValueError: invalid literal for int() with base 10: b'\xa9J'
错误。
感谢。
答案 0 :(得分:1)
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不同,但//
有效两者都是一样的。