151

I have ABC123EFFF.

I want to have 001010101111000001001000111110111111111111 (i.e. binary repr. with, say, 42 digits and leading zeroes).

How?

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • 1
    *I have `ABC123EFFF`* -- `ABC123EFFF` is a string or number (i.e., `0xABC123EFFF`)? – hola Dec 12 '20 at 06:50
  • If it is a string, this lambda I found online years ago might be helpful: 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("ABC123EFFF") '1010101111000001001000111110111111111111' Also works for leading zeros. – buzz Mar 12 '21 at 11:18

22 Answers22

152

For solving the left-side trailing zero problem:


my_hexdata = "1a"

scale = 16 ## equals to hexadecimal

num_of_bits = 8

bin(int(my_hexdata, scale))[2:].zfill(num_of_bits)

It will give 00011010 instead of the trimmed version.

Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
Onedinkenedi
  • 1,553
  • 1
  • 9
  • 2
  • 4
    Calculation for the number of bits is `len(my_hexdata) * log2(scale)`. – Edd Mar 07 '15 at 09:20
  • 11
    Doesn't provide leading zeros if hex string starts with 00. – Dragon Dec 20 '17 at 22:19
  • 2
    @Dragon myhex = '1A' bin(int(myhex, 16))[2:].zfill(8) >>> '00011010' zhex = '00' bin(int(zhex, 16))[2:].zfill(8) >>> '00000000' It appears that this works even when the hex string is '00'. – DeanM Jul 15 '19 at 15:54
  • 1
    @DeanM This does not work when you have leading zeros. E.g., you get `01001000` instead of `0000000001001000` when you've `zhex='0048'`. This [answer](https://stackoverflow.com/a/28913296/4177781) works for me. – arman Jun 15 '21 at 15:22
82

Convert hex to binary

I have ABC123EFFF.

I want to have 001010101111000001001000111110111111111111 (i.e. binary repr. with, say, 42 digits and leading zeroes).

Short answer:

The new f-strings in Python 3.6 allow you to do this using very terse syntax:

>>> f'{0xABC123EFFF:0>42b}'
'001010101111000001001000111110111111111111'

or to break that up with the semantics:

>>> number, pad, rjust, size, kind = 0xABC123EFFF, '0', '>', 42, 'b'
>>> f'{number:{pad}{rjust}{size}{kind}}'
'001010101111000001001000111110111111111111'

Long answer:

What you are actually saying is that you have a value in a hexadecimal representation, and you want to represent an equivalent value in binary.

The value of equivalence is an integer. But you may begin with a string, and to view in binary, you must end with a string.

Convert hex to binary, 42 digits and leading zeros?

We have several direct ways to accomplish this goal, without hacks using slices.

First, before we can do any binary manipulation at all, convert to int (I presume this is in a string format, not as a literal):

>>> integer = int('ABC123EFFF', 16)
>>> integer
737679765503

alternatively we could use an integer literal as expressed in hexadecimal form:

>>> integer = 0xABC123EFFF
>>> integer
737679765503

Now we need to express our integer in a binary representation.

Use the builtin function, format

Then pass to format:

>>> format(integer, '0>42b')
'001010101111000001001000111110111111111111'

This uses the formatting specification's mini-language.

To break that down, here's the grammar form of it:

[[fill]align][sign][#][0][width][,][.precision][type]

To make that into a specification for our needs, we just exclude the things we don't need:

>>> spec = '{fill}{align}{width}{type}'.format(fill='0', align='>', width=42, type='b')
>>> spec
'0>42b'

and just pass that to format

>>> bin_representation = format(integer, spec)
>>> bin_representation
'001010101111000001001000111110111111111111'
>>> print(bin_representation)
001010101111000001001000111110111111111111

String Formatting (Templating) with str.format

We can use that in a string using str.format method:

>>> 'here is the binary form: {0:{spec}}'.format(integer, spec=spec)
'here is the binary form: 001010101111000001001000111110111111111111'

Or just put the spec directly in the original string:

>>> 'here is the binary form: {0:0>42b}'.format(integer)
'here is the binary form: 001010101111000001001000111110111111111111'

String Formatting with the new f-strings

Let's demonstrate the new f-strings. They use the same mini-language formatting rules:

>>> integer = 0xABC123EFFF
>>> length = 42
>>> f'{integer:0>{length}b}'
'001010101111000001001000111110111111111111'

Now let's put this functionality into a function to encourage reusability:

def bin_format(integer, length):
    return f'{integer:0>{length}b}'

And now:

>>> bin_format(0xABC123EFFF, 42)
'001010101111000001001000111110111111111111'    

Aside

If you actually just wanted to encode the data as a string of bytes in memory or on disk, you can use the int.to_bytes method, which is only available in Python 3:

>>> help(int.to_bytes)
to_bytes(...)
    int.to_bytes(length, byteorder, *, signed=False) -> bytes
...

And since 42 bits divided by 8 bits per byte equals 6 bytes:

>>> integer.to_bytes(6, 'big')
b'\x00\xab\xc1#\xef\xff'
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
77
import binascii

binary_string = binascii.unhexlify(hex_string)

Read

binascii.unhexlify

Return the binary data represented by the hexadecimal string specified as the parameter.

rahul
  • 184,426
  • 49
  • 232
  • 263
61
bin(int("abc123efff", 16))[2:]
Glenn Maynard
  • 55,829
  • 10
  • 121
  • 131
  • 13
    If the input is "1a" this gives "11010", not "00011010" which may or may not be what you want. – Matt Good Sep 15 '09 at 07:16
  • 7
    It's quite reasonable to need the leading zeros (and to not need them). You might want the null byte 0x00 to be eight zero bits for example - this is important for some applications. Also the OP has a leading zero in his example (but I suspect that's just random in this case!) – Scott Griffiths Sep 15 '09 at 09:06
33
>>> bin( 0xABC123EFFF )

'0b1010101111000001001000111110111111111111'

Simple
  • 363
  • 3
  • 3
20

Use Built-in format() function and int() function It's simple and easy to understand. It's little bit simplified version of Aaron answer

int()

int(string, base)

format()

format(integer, # of bits)

Example

# w/o 0b prefix
>> format(int("ABC123EFFF", 16), "040b")
1010101111000001001000111110111111111111

# with 0b prefix
>> format(int("ABC123EFFF", 16), "#042b")
0b1010101111000001001000111110111111111111

# w/o 0b prefix + 64bit
>> format(int("ABC123EFFF", 16), "064b")
0000000000000000000000001010101111000001001000111110111111111111

See also this answer

nobody
  • 333
  • 2
  • 7
14
"{0:020b}".format(int('ABC123EFFF', 16))
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
Markus
  • 1,598
  • 2
  • 13
  • 32
10

Here's a fairly raw way to do it using bit fiddling to generate the binary strings.

The key bit to understand is:

(n & (1 << i)) and 1

Which will generate either a 0 or 1 if the i'th bit of n is set.


import binascii

def byte_to_binary(n):
    return ''.join(str((n & (1 << i)) and 1) for i in reversed(range(8)))

def hex_to_binary(h):
    return ''.join(byte_to_binary(ord(b)) for b in binascii.unhexlify(h))

print hex_to_binary('abc123efff')

>>> 1010101111000001001000111110111111111111

Edit: using the "new" ternary operator this:

(n & (1 << i)) and 1

Would become:

1 if n & (1 << i) or 0

(Which TBH I'm not sure how readable that is)

John Montgomery
  • 8,868
  • 4
  • 33
  • 43
  • 1
    I know this is old, but what exactly is the point of the "and 1"? – Goodies Nov 09 '15 at 09:05
  • It's for the old days of python before the ternary operator. The (n & (1 << i)) will either return zero or something other than zero. We only want a one or zero, so that "and 1" is there to ensure that. – John Montgomery Nov 09 '15 at 10:52
  • This script worked best for me to convert a crypto private key in hex to binary for testing purposes. Does anyone know how to split the binary string into 8 bit chunks and print it out? i.e. `01111001` `11111110`. – Edison Mar 29 '18 at 02:53
6

This is a slight touch up to Glen Maynard's solution, which I think is the right way to do it. It just adds the padding element.


    def hextobin(self, hexval):
        '''
        Takes a string representation of hex data with
        arbitrary length and converts to string representation
        of binary.  Includes padding 0s
        '''
        thelen = len(hexval)*4
        binval = bin(int(hexval, 16))[2:]
        while ((len(binval)) &lt thelen):
            binval = '0' + binval
        return binval

Pulled it out of a class. Just take out self, if you're working in a stand-alone script.

RobotHumans
  • 807
  • 10
  • 25
5

I added the calculation for the number of bits to fill to Onedinkenedi's solution. Here is the resulting function:

def hextobin(h):
  return bin(int(h, 16))[2:].zfill(len(h) * 4)

Where 16 is the base you're converting from (hexadecimal), and 4 is how many bits you need to represent each digit, or log base 2 of the scale.

Edd
  • 1,925
  • 1
  • 17
  • 15
3

Replace each hex digit with the corresponding 4 binary digits:

1 - 0001
2 - 0010
...
a - 1010
b - 1011
...
f - 1111
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DmitryK
  • 5,542
  • 1
  • 22
  • 32
  • 3
    Or replace each pair of hex digits with the corresponding 8 binary digits, or replace each triplet of hex digits with the corresponding 12 binary digits ... or replace each 10 hex digits, with the corresponding 40 binary digits - Oops! back where we started! – pavium Sep 15 '09 at 06:52
2

hex --> decimal then decimal --> binary

#decimal to binary 
def d2b(n):
    bStr = ''
    if n < 0: raise ValueError, "must be a positive integer"
    if n == 0: return '0'
    while n > 0:
        bStr = str(n % 2) + bStr
        n = n >> 1    
    return bStr

#hex to binary
def h2b(hex):
    return d2b(int(hex,16))
2
# Python Program - Convert Hexadecimal to Binary
hexdec = input("Enter Hexadecimal string: ")
print(hexdec," in Binary = ", end="")    # end is by default "\n" which prints a new line
for _hex in hexdec:
    dec = int(_hex, 16)    # 16 means base-16 wich is hexadecimal
    print(bin(dec)[2:].rjust(4,"0"), end="")    # the [2:] skips 0b, and the 
moe asal
  • 750
  • 8
  • 24
2

Just use the module coden (note: I am the author of the module)

You can convert haxedecimal to binary there.

  1. Install using pip
pip install coden
  1. Convert
a_hexadecimal_number = "f1ff"
binary_output = coden.hex_to_bin(a_hexadecimal_number)

The converting Keywords are:

  • hex for hexadeimal
  • bin for binary
  • int for decimal
  • _to_ - the converting keyword for the function

So you can also format: e. hexadecimal_output = bin_to_hex(a_binary_number)

math scat
  • 310
  • 8
  • 17
1

Another way:

import math

def hextobinary(hex_string):
    s = int(hex_string, 16) 
    num_digits = int(math.ceil(math.log(s) / math.log(2)))
    digit_lst = ['0'] * num_digits
    idx = num_digits
    while s > 0:
        idx -= 1
        if s % 2 == 1: digit_lst[idx] = '1'
        s = s / 2
    return ''.join(digit_lst)

print hextobinary('abc123efff')
ChristopheD
  • 112,638
  • 29
  • 165
  • 179
1

The binary version of ABC123EFFF is actually 1010101111000001001000111110111111111111

For almost all applications you want the binary version to have a length that is a multiple of 4 with leading padding of 0s.

To get this in Python:

def hex_to_binary( hex_code ):
  bin_code = bin( hex_code )[2:]
  padding = (4-len(bin_code)%4)%4
  return '0'*padding + bin_code

Example 1:

>>> hex_to_binary( 0xABC123EFFF )
'1010101111000001001000111110111111111111'

Example 2:

>>> hex_to_binary( 0x7123 )
'0111000100100011'

Note that this also works in Micropython :)

Stefan
  • 698
  • 7
  • 9
0

i have a short snipped hope that helps :-)

input = 'ABC123EFFF'
for index, value in enumerate(input):
    print(value)
    print(bin(int(value,16)+16)[3:])

string = ''.join([bin(int(x,16)+16)[3:] for y,x in enumerate(input)])
print(string)

first i use your input and enumerate it to get each symbol. then i convert it to binary and trim from 3th position to the end. The trick to get the 0 is to add the max value of the input -> in this case always 16 :-)

the short form ist the join method. Enjoy.

Johannes Knust
  • 891
  • 1
  • 11
  • 18
0
HEX_TO_BINARY_CONVERSION_TABLE = {
                              '0': '0000',

                              '1': '0001',

                              '2': '0010',

                              '3': '0011',

                              '4': '0100',

                              '5': '0101',

                              '6': '0110',

                              '7': '0111',

                              '8': '1000',

                              '9': '1001',

                              'a': '1010',

                              'b': '1011',

                              'c': '1100',

                              'd': '1101',

                              'e': '1110',

                              'f': '1111'}

def hex_to_binary(hex_string):
    binary_string = ""
    for character in hex_string:
        binary_string += HEX_TO_BINARY_CONVERSION_TABLE[character]
    return binary_string

when I time hex_to_binary("123ade")

  %timeit hex_to_binary("123ade")

here is the result:

 316 ns ± 2.52 ns per loop

Alternatively, you could use "join" method:

def hex_to_binary_join(hex_string):
    hex_array=[]
    for character in hex_string:
        hex_array.append(HEX_TO_BINARY_CONVERSION_TABLE[character])
    return "".join(hex_array)

I timed this too:

    %timeit hex_to_binary_join("123ade")
       397 ns ± 4.64 ns per loop 
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
-1
a = raw_input('hex number\n')
length = len(a)
ab = bin(int(a, 16))[2:]
while len(ab)<(length * 4):
    ab = '0' + ab
print ab
Ashwini
  • 9
  • 1
-1
import binascii
hexa_input = input('Enter hex String to convert to Binary: ')
pad_bits=len(hexa_input)*4
Integer_output=int(hexa_input,16)
Binary_output= bin(Integer_output)[2:]. zfill(pad_bits)
print(Binary_output)
"""zfill(x) i.e. x no of 0 s to be padded left - Integers will overwrite 0 s
starting from right side but remaining 0 s will display till quantity x
[y:] where y is no of output chars which need to destroy starting from left"""
-1
 def conversion():
    e=raw_input("enter hexadecimal no.:")
    e1=("a","b","c","d","e","f")
    e2=(10,11,12,13,14,15)
    e3=1
    e4=len(e)
    e5=()
    while e3<=e4:
        e5=e5+(e[e3-1],)
        e3=e3+1
    print e5
    e6=1
    e8=()
    while e6<=e4:
        e7=e5[e6-1]
        if e7=="A":
            e7=10
        if e7=="B":
            e7=11
        if e7=="C":
            e7=12
        if e7=="D":
            e7=13
        if e7=="E":
            e7=14
        if e7=="F":
            e7=15
        else:
            e7=int(e7)
        e8=e8+(e7,)
        e6=e6+1
    print e8

    e9=1
    e10=len(e8)
    e11=()
    while e9<=e10:
        e12=e8[e9-1]
        a1=e12
        a2=()
        a3=1 
        while a3<=1:
            a4=a1%2
            a2=a2+(a4,)
            a1=a1/2
            if a1<2:
                if a1==1:
                    a2=a2+(1,)
                if a1==0:
                    a2=a2+(0,)
                a3=a3+1
        a5=len(a2)
        a6=1
        a7=""
        a56=a5
        while a6<=a5:
            a7=a7+str(a2[a56-1])
            a6=a6+1
            a56=a56-1
        if a5<=3:
            if a5==1:
                a8="000"
                a7=a8+a7
            if a5==2:
                a8="00"
                a7=a8+a7
            if a5==3:
                a8="0"
                a7=a8+a7
        else:
            a7=a7
        print a7,
        e9=e9+1
-7
no=raw_input("Enter your number in hexa decimal :")
def convert(a):
    if a=="0":
        c="0000"
    elif a=="1":
        c="0001"
    elif a=="2":
        c="0010"
    elif a=="3":
        c="0011"
    elif a=="4":
        c="0100"
    elif a=="5":
        c="0101"
    elif a=="6":
        c="0110"
    elif a=="7":
        c="0111"
    elif a=="8":
        c="1000"
    elif a=="9":
        c="1001"
    elif a=="A":
        c="1010"
    elif a=="B":
        c="1011"
    elif a=="C":
        c="1100"
    elif a=="D":
        c="1101"
    elif a=="E":
        c="1110"
    elif a=="F":
        c="1111"
    else:
        c="invalid"
    return c

a=len(no)
b=0
l=""
while b<a:
    l=l+convert(no[b])
    b+=1
print l
warunn
  • 39