Objective: Convert binary to string
Example: 0111010001100101011100110111010001100011011011110110010001100101 -> testCode (without space)
I use a dictionary and my function, i search a better way and more efficient
from textwrap import wrap
DICO = {'\x00': '00', '\x04': '0100', '\x08': '01000', '\x0c': '01100',
'\x10': '010000', '\x14': '010100', '\x18': '011000', '\x1c': '011100',
' ': '0100000', '$': '0100100', '(': '0101000', ',': '0101100', '0': '0110000',
'4': '0110100', '8': '0111000', '<': '0111100', '@': '01000000',
'D': '01000100', 'H': '01001000', 'L': '01001100', 'P': '01010000',
'T': '01010100', 'X': '01011000', '\\': '01011100', '`': '01100000',
'd': '01100100', 'h': '01101000', 'l': '01101100', 'p': '01110000',
't': '01110100', 'x': '01111000', '|': '01111100', '\x03': '011',
'\x07': '0111', '\x0b': '01011', '\x0f': '01111', '\x13': '010011',
'\x17': '010111', '\x1b': '011011', '\x1f': '011111', '#': '0100011',
"'": '0100111', '+': '0101011', '/': '0101111', '3': '0110011', '7': '0110111',
';': '0111011', '?': '0111111', 'C': '01000011', 'G': '01000111',
'K': '01001011', 'O': '01001111', 'S': '01010011', 'W': '01010111',
'[': '01011011', '_': '01011111', 'c': '01100011', 'g': '01100111',
'k': '01101011', 'o': '01101111', 's': '01110011', 'w': '01110111',
'{': '01111011', '\x7f': '01111111', '\x02': '010', '\x06': '0110',
'\n': '01010', '\x0e': '01110', '\x12': '010010', '\x16': '010110',
'\x1a': '011010', '\x1e': '011110', '"': '0100010', '&': '0100110',
'*': '0101010', '.': '0101110', '2': '0110010', '6': '0110110', ':': '0111010',
'>': '0111110', 'B': '01000010', 'F': '01000110', 'J': '01001010',
'N': '01001110', 'R': '01010010', 'V': '01010110', 'Z': '01011010',
'^': '01011110', 'b': '01100010', 'f': '01100110', 'j': '01101010',
'n': '01101110', 'r': '01110010', 'v': '01110110', 'z': '01111010',
'~': '01111110', '\x01': '01', '\x05': '0101', '\t': '01001', '\r': '01101',
'\x11': '010001', '\x15': '010101', '\x19': '011001', '\x1d': '011101',
'!': '0100001', '%': '0100101', ')': '0101001', '-': '0101101',
'1': '0110001', '5': '0110101', '9': '0111001', '=': '0111101',
'A': '01000001', 'E': '01000101', 'I': '01001001', 'M': '01001101',
'Q': '01010001', 'U': '01010101', 'Y': '01011001', ']': '01011101',
'a': '01100001', 'e': '01100101', 'i': '01101001', 'm': '01101101',
'q': '01110001', 'u': '01110101', 'y': '01111001', '}': '01111101'}
def decrypt(binary):
"""Function to convert binary into string"""
binary = wrap(binary, 8)
ch = ''
for b in binary:
for i, j in DICO.items():
if j == b:
ch += i
return ch
thank by advance,
''.join([ chr(int(p, 2)) for p in wrap(binstr, 8) ])
What this does: wrap
first splits your string up into chunks of 8. Then, I iterate through each one, and convert it to an integer (base 2). Each of those converted integer now get covered to a character with chr
. Finally I wrap it all up with a ''.join
to smash it all together.
A bit more of a breakdown of each step of the chr(int(p, 2))
:
>>> int('01101010', 2)
106
>>> chr(106)
'j'
To make it fit into your pattern above:
def decrypt(binary):
"""Function to convert binary into string"""
binary = wrap(binary, 8)
ch = ''
for b in binary:
ch += chr(int(b, 2))
return ch
or
def decrypt(binary):
"""Function to convert binary into string"""
return ''.join([ chr(int(p, 2)) for p in wrap(binary, 8) ])
This is definitely faster since it is just doing the math in place, not iterating through the dictionary over and over. Plus, it is more readable.
If execution speed it the most important for you, why not invert the roles of keys and values in your dict?! (If you also need the current dict, you could created an inverted version like this {v:k for k, v in DICO.items()}
)
Now, you find directly the searched translation by key instead of looping through the whole dict.
Your new function would look like this:
def decrypt2(binary):
"""Function to convert binary into string"""
binary = wrap(binary, 8)
ch = ''
for b in binary:
if b in DICO_INVERTED:
ch += DICO_INVERTED[b]
return ch
Depending on the size of your binary string, you could gain some time by changing the way you construct your output-string (see Efficient String Concatenation in Python or performance tips - string concatenation). Using join
seems promising. I would give it a try: ''.join(DICO_INVERTED.get(b, '') for b in binary)
did you try
def decrypt(binary):
"""Function to convert binary into string"""
return ''.join(( chr(int(p, 2)) for p in grouper(8,binary,'') ))
where grouper is taken from here http://docs.python.org/library/itertools.html#recipes
or
def decrypt2(binary):
"""Function to convert binary into string"""
return ''.join(( DICO_INVERTED[p] for p in grouper(8,binary,'') ))
that avoids to create temporary list
EDIT as I was choisen to be the "right" answer I have to confess that I used the other answers. The point is here not to use generator list but generator expression and iterators
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With