Convert a Python int into a big-endian string of bytes

Python

Python Problem Overview


I have a non-negative int and I would like to efficiently convert it to a big-endian string containing the same data. For example, the int 1245427 (which is 0x1300F3) should result in a string of length 3 containing three characters whose byte values are 0x13, 0x00, and 0xf3.

My ints are on the scale of 35 (base-10) digits.

How do I do this?

Python Solutions


Solution 1 - Python

You can use the struct module:

import struct
print(struct.pack('>I', your_int))

'>I' is a format string. > means big endian and I means unsigned int. Check the documentation for more format chars.

Solution 2 - Python

In Python 3.2+, you can use int.to_bytes:

If you don't want to specify the size

>>> n = 1245427
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big') or b'\0'
b'\x13\x00\xf3'

If you don't mind specifying the size

>>> (1245427).to_bytes(3, byteorder='big')
b'\x13\x00\xf3'

Solution 3 - Python

This is fast and works for small and (arbitrary) large ints:

def Dump(n): 
  s = '%x' % n
  if len(s) & 1:
    s = '0' + s
  return s.decode('hex')
print repr(Dump(1245427))  #: '\x13\x00\xf3'

Solution 4 - Python

Probably the best way is via the built-in struct module:

>>> import struct
>>> x = 1245427
>>> struct.pack('>BH', x >> 16, x & 0xFFFF)
'\x13\x00\xf3'
>>> struct.pack('>L', x)[1:]  # could do it this way too
'\x13\x00\xf3'

Alternatively -- and I wouldn't usually recommend this, because it's mistake-prone -- you can do it "manually" by shifting and the chr() function:

>>> x = 1245427
>>> chr((x >> 16) & 0xFF) + chr((x >> 8) & 0xFF) + chr(x & 0xFF)
'\x13\x00\xf3'

Out of curiosity, why do you only want three bytes? Usually you'd pack such an integer into a full 32 bits (a C unsigned long), and use struct.pack('>L', 1245427) but skip the [1:] step?

Solution 5 - Python

def tost(i):
  result = []
  while i:
    result.append(chr(i&0xFF))
    i >>= 8
  result.reverse()
  return ''.join(result)

Solution 6 - Python

Single-source Python 2/3 compatible version based on @pts' answer:

#!/usr/bin/env python
import binascii

def int2bytes(i):
    hex_string = '%x' % i
    n = len(hex_string)
    return binascii.unhexlify(hex_string.zfill(n + (n & 1)))

print(int2bytes(1245427))
# -> b'\x13\x00\xf3'

Solution 7 - Python

The shortest way, I think, is the following:

import struct
val = 0x11223344
val = struct.unpack("<I", struct.pack(">I", val))[0]
print "%08x" % val

This converts an integer to a byte-swapped integer.

Solution 8 - Python

Using the bitstring module:

>>> bitstring.BitArray(uint=1245427, length=24).bytes
'\x13\x00\xf3'

Note though that for this method you need to specify the length in bits of the bitstring you are creating.

Internally this is pretty much the same as Alex's answer, but the module has a lot of extra functionality available if you want to do more with your data.

Solution 9 - Python

Very easy with pwntools , the tools created for software hacking

(Un-ironically, I stumbled across this thread and tried solutions here, until I realised there exists conversion functionality in pwntools)

import pwntools

x2 = p32(x1)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfishView Question on Stackoverflow
Solution 1 - PythonAyman HouriehView Answer on Stackoverflow
Solution 2 - PythonJanus TroelsenView Answer on Stackoverflow
Solution 3 - PythonptsView Answer on Stackoverflow
Solution 4 - PythonBen HoytView Answer on Stackoverflow
Solution 5 - PythonAlex MartelliView Answer on Stackoverflow
Solution 6 - PythonjfsView Answer on Stackoverflow
Solution 7 - Pythonuser420783View Answer on Stackoverflow
Solution 8 - PythonScott GriffithsView Answer on Stackoverflow
Solution 9 - PythonTAbdiukovView Answer on Stackoverflow