3

In python3 I have some bytes. I want to export them to C source code. Outside python I use "xxd -i binary_file" command.

Example:

x = b'abc123'
print(bytes_to_c_arr(x))
# should output:
unsigned char x[] = { 0x61, 0x62, 0x63, 0x31, 0x32, 0x33 };

Is there ready method or handy one-liner? I can do away without type declaration, only bytes for contents would suffice.

MateuszL
  • 2,751
  • 25
  • 38

3 Answers3

2
1. print([hex(i) for in x]) 

2. print(a.hex())

Results will be:

1. ['0x61', '0x62', '0x63', '0x31', '0x32', '0x33']
2. '616263313233'
2

In case you want to use caps or not:

def bytes_to_c_arr(data, lowercase=True):
    return [format(b, '#04x' if lowercase else '#04X') for b in data]

x = b'abc123'
print("unsigned char x[] = {{{}}}".format(", ".join(bytes_to_c_arr(x))))
print("unsigned char x[] = {{{}}}".format(", ".join(bytes_to_c_arr(x, False))))

# output: unsigned char x[] = {0x61, 0x62, 0x63, 0x31, 0x32, 0x33}
#         unsigned char x[] = {0X61, 0X62, 0X63, 0X31, 0X32, 0X33}
BPL
  • 9,632
  • 9
  • 59
  • 117
0

Here is a very fast way (134 MiB/s on Intel i7-8700, Python 2) that avoids iterating using slow, interpreted Python loops and iterates in optimized code

import binascii
x=b'abc123'
hex=binascii.b2a_hex(x)
# add \x prefix
hex2=bytearray(4*len(b))
hex2[0::4]='\\'*len(b)
hex2[1::4]='x'*len(b)
hex2[2::4]=hex[0::2]
hex2[3::4]=hex[1::2]

Using your example, this will generate these hex literals

\x61\x62\x63\x31\x32\x33

Just put this inside a double quoted string. I've omitted that code for brevity.

Yale Zhang
  • 1,447
  • 12
  • 30