As i come across this again and again:
How do you turn a hex string like "c3a4c3b6c3bc"
into a nice binary string like this: "11000011 10100100 11000011 10110110 11000011 10111100"
?
The solution is based on the Python 2.6 new string formatting:
>>> "{0:8b}".format(int("c3",16))
'11000011'
Which can be decomposed into 4 bit for each hex char like this: (notice the 04b, which means 0-padded 4chars long binary string):
>>> "{0:04b}".format(int("c",16)) + "{0:04b}".format(int("3",16))
'11000011'
OK, now we could easily do this for all hex chars "".join(["{0:04b}".format(int(c,16)) for c in "c3a4c3b6"])
and done, but usually we want a blank every 8 bits from the right to left… And looping from the right pairwise is a bit more complicated… Oh and what if the number of bits is uneven?
So the solution looks like this:
>>> binary = lambda x: " ".join(reversed( [i+j for i,j in zip( *[ ["{0:04b}".format(int(c,16)) for c in reversed("0"+x)][n::2] for n in [1,0] ] ) ] ))
>>> binary("c3a4c3b6c3bc")
'11000011 10100100 11000011 10110110 11000011 10111100'
It takes the hex string x
, first of all concatenates a "0"
to the left (for the uneven case), then reverses the string, converts every char into a 4-bit binary string, then collects all uneven indices of this list, zips them to all even indices, for each in the pairs-list concatenates them to 8-bit binary strings, reverses again and joins them together with a ” ” in between. In case of an even number the added 0 falls out, because there’s no one to zip with, if uneven it zips with the first hex-char.
Yupp, I like 1liners 😉
Update: Btw, it’s very easy to combine this with binascii.hexlify
to get the binary representation of some byte-string:
>>> import binascii
>>> binascii.hexlify('jörn')
'6ac3b6726e'
>>> binary(binascii.hexlify('jörn'))
'01101010 11000011 10110110 01110010 01101110'
Useful. Like it.
Thann you vert much, a simply powerful script working as well. Perfect 🙂
I’m having an issue implementing this (and please forgive me for being such a newbie)…
I have a file with 300 some odd lines such as:
7E405100C6710110CCFE1F003901000000000000037E
I’ve integrated your bit as follows:
pre_file = ‘parser.log’
stripped_file = ‘stripped.txt’
binary_file = ‘binary.txt’
binary = lambda x: ” “.join(reversed( [i+j for i,j in zip( *[ [“{0:04b}”.format(int(c,16)) for c in reversed(“0″+x)][n::2] for n in [1,0] ] ) ] ))
open(‘stripped_file’, “w”).write(open(pre_file).read().replace(” “,””) .strip())
open(‘binary_file’, “w”).write(open(stripped_file).read() .binary(x))
When I run it – I get the following error:
open(‘binary_file’, “w”).write(open(stripped_file).read() .binary(x))
AttributeError: ‘str’ object has no attribute ‘binary’
I’m at a loss and appreciate your assistance in advance!
hmm, your code looks a bit confused, you’re trying to use
.binary(x)
on the result of.read()
, the latter is a string and we didn’t register thebinary
function as a string method…i have to guess a lot: you probably want to turn that around and also iterate over your opened file and keep newlines:
Yeah – I obscured a bit too much. Basically, I have a file with 300+ lines like:
7E405100CB71FA1FCCFE1F003901000000000000F67E
7E405100C6710110CCFE1F003901000000000000037E
7E405100C67105108CFE1F0039010000000000003F7E
7E405100C47108108CFE1F0039010000000000003E7E
7E405100C27106105CFE1F003901000000000000727E
7E405100BF7105105CFE1F003901000000000000767E
I need to turn these HEX bytes into a binary bitmap output to another file like:
0111 1110 0100 0000 0101 0001 0000 0000 1100 1011 0111 0001…..
0111 1110 0100 0000 0101 0001 0000 0000 1100 0110 0111 00011….
Is this enough information? Will the fix you suggested above create the output I need?
Hi Joern,
Could you help me to understand why your code can pick out even and odd elements in a list? Specifically, how does
[n::2]
for n in[1,0]
work? I try it out on interpreter and get an error. But, if I combine it with a[[1,2,3,4,5][n::2] for n in [1, 0] ]
[[2, 4], [1, 3, 5]]
[ [n::2] for n in [1, 0] ]
File "", line 1
[ [n::2] for n in [1, 0] ]
^
SyntaxError: invalid syntax
Thank you,
Lawrence
I think you’re confused by
[]
being used for lists (e.g.,[1,2,3]
) and slices (e.g.,something[start:stop:step]
). The slightly sloppy takeaway here is: slices do not exist without something in front of them.