我有以下Python代码可以做到这一点:
from struct import pack as _pack def packl(lnum, pad = 1): if lnum < 0: raise RangeError("Cannot use packl to convert a negative integer " "to a string.") count = 0 l = [] while lnum > 0: l.append(lnum & 0xffffffffffffffffL) count += 1 lnum >>= 64 if count <= 0: return '\0' * pad elif pad >= 8: lens = 8 * count % pad pad = ((lens != 0) and (pad - lens)) or 0 l.append('>' + 'x' * pad + 'Q' * count) l.reverse() return _pack(*l) else: l.append('>' + 'Q' * count) l.reverse() s = _pack(*l).lstrip('\0') lens = len(s) if (lens % pad) != 0: return '\0' * (pad - lens % pad) + s else: return s
这大约需要174个usec才能转换2**9700 - 1为我的计算机上的字节字符串。如果我愿意使用特定于Python 2.7和Python 3.x的bit_length方法,可以通过l在开始时就将数组预先分配为恰好正确的大小并使用l[something] =语法而不是来将其缩短到159个usecs l.append。
2**9700 - 1
bit_length
l
l[something] =
l.append
我有什么可以做的更快?这将用于转换密码术中使用的大质数以及一些(但不是很多)较小的数。
编辑
目前,这是Python <3.2中最快的选项,任一方向花费的时间大约是接受答案的一半:
def packl(lnum, padmultiple=1): """Packs the lnum (which must be convertable to a long) into a byte string 0 padded to a multiple of padmultiple bytes in size. 0 means no padding whatsoever, so that packing 0 result in an empty string. The resulting byte string is the big-endian two's complement representation of the passed in long.""" if lnum == 0: return b'\0' * padmultiple elif lnum < 0: raise ValueError("Can only convert non-negative numbers.") s = hex(lnum)[2:] s = s.rstrip('L') if len(s) & 1: s = '0' + s s = binascii.unhexlify(s) if (padmultiple != 1) and (padmultiple != 0): filled_so_far = len(s) % padmultiple if filled_so_far != 0: s = b'\0' * (padmultiple - filled_so_far) + s return s def unpackl(bytestr): """Treats a byte string as a sequence of base 256 digits representing an unsigned integer in big-endian format and converts that representation into a Python integer.""" return int(binascii.hexlify(bytestr), 16) if len(bytestr) > 0 else 0
在Python 3.2中,int该类具有to_bytes和from_bytes函数,它们可以 比 上述方法更快地完成此任务。
int
to_bytes
from_bytes
为了完整性和将来读者对该问题的了解:
从Python 3.2开始,提供了一些函数int.from_bytes(),int.to_bytes()这些函数可以按字节顺序选择在bytes和int对象之间进行转换。
int.from_bytes()
int.to_bytes()
bytes