Python 里怎么把一个大整数变成 bytes?

2013-06-04 06:54:09 +08:00
 y0
现在知道两种方法:

一种是 import struct, 另一种是 import binascii.

>>> a = 3312345
>>> struct.pack('>I', a)
b'\x002\x8a\xd9'
>>> binascii.unhexlify(hex(a).lstrip('0x'))
b'2\x8a\xd9'

第一种的话,a 不能太大,超过 2^32 就不行了。(另外那个 \x00 还得处理掉)
但第二种好像又不是很优雅。哪位有高招? One-liner preferred.

a 是一个 256 bits 的数。
6215 次点击
所在节点    Python
15 条回复
sillyousu
2013-06-04 07:06:57 +08:00
这个256位的大数一定要变成一个bytes?

如果可以变几个bytes的话,struct那里多放几个I行不?
zuroc
2013-06-04 07:24:06 +08:00
In [10]: msgpack.dumps(2**64-1)
Out[10]: '\xcf\xff\xff\xff\xff\xff\xff\xff\xff'

In [11]: msgpack.dumps(2**64-1)
Out[11]: '\xcf\xff\xff\xff\xff\xff\xff\xff\xff'

In [12]: msgpack.dumps(1)
Out[12]: '\x01'

In [13]: msgpack.dumps(2)
Out[13]: '\x02'

In [14]: msgpack.dumps(0)
Out[14]: '\x00'
y0
2013-06-04 07:43:02 +08:00
@zuroc >>> msgpack.dumps(2078388773771218783740288990824871144635246987129597257065)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "_packer.pyx", line 259, in msgpack._packer.packb (msgpack/_packer.cpp:259)
File "_packer.pyx", line 184, in msgpack._packer.Packer.pack (msgpack/_packer.cpp:184)
File "_packer.pyx", line 124, in msgpack._packer.Packer._pack (msgpack/_packer.cpp:124)
OverflowError: int too big to convert
zuroc
2013-06-04 08:10:09 +08:00
max 2**64-1
y0
2013-06-04 08:29:37 +08:00
@zuroc 我都说了 256 bit 了。
lyjyiran
2013-06-04 08:30:26 +08:00
>>> val=2078388773771218783740288990824871144635246987129597257065
>>> bytes = hex(val).rstrip('L')[2:].decode('hex')
>>> bytes
'T\xc3d+\x1bq\x8d\x7f\xb0\x12\xdf\xea\x1fd\x04\x14\xbbwG\xd6\xd1\xc8\xe5i'
>>> int(bytes.encode('hex'),16)
2078388773771218783740288990824871144635246987129597257065L
clowwindy
2013-06-04 09:45:36 +08:00
一个循环就搞定的事,何必这样呢
y0
2013-06-04 11:51:59 +08:00
@clowwindy 没必要用循环。我最后采用的是
binascii.unhexlify(hex(a).[2:]).
mindcat
2013-06-04 11:53:32 +08:00
@y0 hex(2**256-1)
具体看着办 =w=
zuroc
2013-06-04 12:13:07 +08:00
In [5]: marshal.dumps(22222222222222222222222222222222222222222)
Out[5]: 'l\t\x00\x00\x00\x8ecq\x1c\x8e3\xd1"\xf6\x1e5J\xfa\x08)\x12NA'

In [6]: marshal.dumps(22222222222222222222222222222222222222222222222222)
Out[6]: 'l\x0b\x00\x00\x00\x8ecq\x1c\x8ec\xb1Pi<AG\xb5\x0b\x0f6Yp\xd0}\xd1<'

In [7]: marshal.dumps(2222222222222222222222222222222222222222222222222222222222222222)
Out[7]: "l\x0f\x00\x00\x00\x8ecq\x1c\x8ecq\x1c\xae\n\x0f\n'i6?\x18\n'u\xa5Y\x11G\xcbF\xdc,\x01\x00"
y0
2013-06-04 15:17:25 +08:00
@zuroc 好像字节序是反的……

>>> binascii.unhexlify(hex(a).lstrip('0x'))
b'2\x8a\xd9'
>>> marshal.dumps(a)
b'i\xd9\x8a2\x00'
ruoyu0088
2013-06-09 16:58:57 +08:00
Python3的话可以用int的to_bytes()方法。

In [14]: a = 3**100

a.to_bytes(a.bit_length()//8 + 1, "little")

Out[14]:
b'\xd1\x138\xcfU}\x94\xd6u\xf7A[Vh7g\xcaSFZ'
y0
2013-06-09 17:16:00 +08:00
@ruoyu0088 嗯,昨天才学会这个。不过这个必须 20 bytes 以内。

现在用的是

def to_bytes(u_int,length):
return bitstring.BitArray(uint=u_int,length=length).bytes
xierch
2013-06-09 17:21:36 +08:00
还是直接点写循环吧.. 何必纠结于一行,效率反而低了..

i = 2078388773771218783740288990824871144635246987129597257065
s = ''
while i:
s = chr(i & 255) + s
i = i >> 8
ruoyu0088
2013-06-09 19:42:26 +08:00
@y0 没有20bytes的限制,例如:

In [7]:

a = 3 ** 500

a.to_bytes(200, "little")

Out[7]:

b'\x11\xdd\xd97\xdbq\x0f\xcfg|t9R\xca\x03Z\x8cj\x10\x0e\x83\xd9W\x03\xa7\xb9\x9f\x91\xfd\xfc\x9a\xe2\xe5\x80u\xd0\xe7\x9fv\x88\xb7W\xf8h\xc7\xdeg\x10\xd7\x8b\xa2u(`u?)\xc1\x06\x82l\x10\xf6R\xcc\x8b\x16\xa6\xda\x8d\xdf\xee\xbfq\xfc\x07`\xb3D\xbaA\x8dzq\x18\xbd\xa8nS8\xe4\x04v?V\xe0,]e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/71129

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX