如何将整数转换为可变长度字节串?

5 python byte integer bit-manipulation endianness

我想转换一个整数(intlong)一个big-endian字节字符串.字节串必须是可变长度的,因此只使用最小字节数(前面数据的总长度是已知的,因此可以推断出可变长度).

我目前的解决方案是

import bitstring

bitstring.BitString(hex=hex(456)).tobytes()
Run Code Online (Sandbox Code Playgroud)

这显然取决于机器的字节顺序并给出错误的结果,因为0位是追加而没有前置.

有没有人知道如何做到这一点,而不做任何关于一个长度或结束的假设int

Joh*_*hin 6

像这样的东西.未经测试(直到下一次编辑).对于Python 2.x. 假设n> 0.

tmp = []
while n:
    n, d = divmod(n, 256)
    tmp.append(chr(d))
result = ''.join(tmp[::-1])
Run Code Online (Sandbox Code Playgroud)

编辑:测试.

如果你不阅读手册但是喜欢bitbashing,而不是divmodcaper,试试这个:

d = n & 0xFF; n >>= 8
Run Code Online (Sandbox Code Playgroud)

编辑2:如果您的数字相对较小,以下可能会更快:

result = ''
while n:
    result = chr(n & 0xFF) + result
    n >>= 8
Run Code Online (Sandbox Code Playgroud)

编辑3:第二种方法不假设int已经是bigendian.这是在臭名昭着的小环境中发生的事情:

Python 2.7 (r27:82525, Jul  4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> n = 65539
>>> result = ''
>>> while n:
...     result = chr(n & 0xFF) + result
...     n >>= 8
...
>>> result
'\x01\x00\x03'
>>> import sys; sys.byteorder
'little'
>>>
Run Code Online (Sandbox Code Playgroud)


Sco*_*ths 0

如果您使用的是 Python 2.7 或更高版本,则可以使用该bit_length方法将长度四舍五入到下一个字节:

>>> i = 456
>>> bitstring.BitString(uint=i, length=(i.bit_length()+7)/8*8).bytes
'\x01\xc8'
Run Code Online (Sandbox Code Playgroud)

否则,您可以只测试整个字节并在需要时在开头填充零半字节:

>>> s = bitstring.BitString(hex=hex(i))
>>> ('0x0' + s if s.len%8 else s).bytes
'\x01\xc8'
Run Code Online (Sandbox Code Playgroud)