How to convert an integer string to a variable length string?

I want to convert an integer ( intor long) byte string to a large end. The byte string must have a variable length, so only the minimum number of bytes is used (the total length of the previous data is known, so you can determine the length of the variable).

My current solution

import bitstring

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

It obviously depends on the finiteness of the machine and gives false results, because 0 bits are added and not added.

Does anyone know a way to do this without making any assumptions about length or endianess int?

+5
source share
4

Python 2.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'
0

- . Untested ( ). Python 2.x. , n > 0.

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

: .

, , divmod, :

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

2: , :

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

3: , int . :

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'
>>>
+6

struct itertools:

>>> 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)
+1

I reformulated John Machins second answer in one line for use on my server:

def bytestring(n):
    return ''.join([chr((n>>(i*8))&0xFF) for i in range(n.bit_length()/8,-1,-1)])

I found that the second method, using a bit shift, was faster for large and small numbers, and not just for small numbers.

0
source

All Articles