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

2024-05-14 18:28:46 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我现在的解决方案是

import bitstring

bitstring.BitString(hex=hex(456)).tobytes()

这显然取决于机器的结束性,并给出错误的结果,因为0位是附加的,而不是前置的。

有没有人知道这样做的方法,而不必对int的长度或端点做任何假设?


Tags: 数据字符串import机器字节整数解决方案long
3条回答

使用structitertools的解决方案:

>>> import itertools, struct
>>> "".join(itertools.dropwhile(lambda c: not(ord(c)), struct.pack(">i", 456))) or chr(0)
'\x01\xc8'

我们可以使用一个简单的字符串条来删除itertools

>>> struct.pack(">i", 456).lstrip(chr(0)) or chr(0)
'\x01\xc8'

或者甚至使用递归函数删除struct

def to_bytes(n): 
    return ([chr(n & 255)] + to_bytes(n >> 8) if n > 0 else [])

"".join(reversed(to_bytes(456))) or chr(0)

如果使用的是Python2.7或更高版本,则可以使用bit_length方法将长度舍入到下一个字节:

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

否则,您可以只测试整个字节数,如果需要,可以在开始时用零字节填充:

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

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

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

编辑:已测试。

如果您不阅读手册,但喜欢使用bitbashing,而不是divmod开玩笑,请尝试以下操作:

d = n & 0xFF; n >>= 8

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

result = ''
while n:
    result = chr(n & 0xFF) + result
    n >>= 8

编辑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'
>>>

相关问题 更多 >

    热门问题