Tom
Tom

Reputation: 332

Python Binary to hex conversion preserving leading zeroes

I was wanting to convert a 576 bit binary number to hex so I wrote the following python script. While writing it was fun, i believe it to be massive, ugly, and most likely unnecessarily complicated. I was wondering if anyone new of a more efficient way to do this using some of the python built in. The issue I had using any that I could find was preserving the leading zeroes as it is absolutely critical. Below is the input and output i used to test and the code I wrote.

The input:

000011110111101011000101

The output:

0f7ac5

Code

file = open("binforhex.txt",'r')
stream = file.read()

num = []
byte = []
hexOut = []
n = 0

print stream

for x in stream:
    num.append(x)


while n < len(num):
    byte.append(int(num[n]))
    if n > 1:
        if (n + 1) % 4  == 0:
            if cmp([0, 0, 0, 0],byte) == 0 :
                hexOut.append('0')
            elif cmp([0, 0, 0, 1],byte) == 0 :
                hexOut.append('1')
            elif cmp([0, 0, 1, 0],byte) == 0 :
                hexOut.append('2')
            elif cmp([0, 0, 1, 1],byte) == 0 :
               hexOut.append('3')
            elif cmp([0, 1, 0, 0],byte) == 0:
                hexOut.append('4')
            elif cmp([0, 1, 0, 1],byte) == 0:
                hexOut.append('5')
            elif cmp([0, 1, 1, 0],byte) == 0:
                hexOut.append('6')
            elif cmp([0, 1, 1, 1],byte) == 0:
                hexOut.append('7')
            elif cmp([1, 0, 0, 0],byte) == 0:
                hexOut.append('8')
            elif cmp([1, 0, 0, 1],byte) == 0:
                hexOut.append('9')
            elif cmp([1, 0, 1, 0],byte) == 0:
                hexOut.append('a')
            elif cmp([1, 0, 1, 1],byte) == 0:
                hexOut.append('b')
            elif cmp([1, 1, 0, 0],byte) == 0:
                hexOut.append('c')
            elif cmp([1, 1, 0, 1],byte) == 0:
                hexOut.append('d')
            elif cmp([1, 1, 1, 0],byte) == 0:
                hexOut.append('e')
            elif cmp([1, 1, 1, 1],byte) == 0 :
                hexOut.append('f')
            byte.pop()
            byte.pop()
            byte.pop()
            byte.pop()
    n += 1
print ''.join(hexOut)

Upvotes: 1

Views: 5014

Answers (2)

Alex Martelli
Alex Martelli

Reputation: 882113

The total number of hex digits you want, starting from binary string b, is

hd = (len(b) + 3) // 4

So...:

x = '%.*x' % (hd, int('0b'+b, 0))

should give you what you want (with a '0x' prefix that you can easily slice away of course, just use x[2:]).

Added: the format string '%.*x' means "format as hexadecimal to a length as per supplied parameter, with leading zeros". The "supplied parameter" here is hd, the total number of hex digits we require.

The simple, key concept is to think in terms of total number of digits (binary on input, hex on output) rather than the "number of leading zeros" in each case -- the latter will just fall into place. E.g, if the input binary string has 576 bits, no matter how many of them are "leading zeros", you want the output hex string to have 576 // 4, i.e, 144, hex digits, so that's what hd will be set to -- and that's how many digits you'll get by this formatting (as many of them will be "leading zeros" as needed -- no more, no less).

Upvotes: 4

MattDMo
MattDMo

Reputation: 102892

Did you know there's a hex() builtin? It converts any number (including binary numbers, starting with 0b) to a hex string:

>>> hex(0b000011110111101011000101)
'0xf7ac5'

Upvotes: 0

Related Questions