Binary for a string, better than a dictionary?

Purpose: convert binary to string

Example: 01110100011001010111001101110100011000110110111101100100010101101 β†’ testCode (without space)

I use the dictionary and my function, I am looking for 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 

Thanks in advance,

+6
source share
3 answers

You tried

 def decrypt(binary): """Function to convert binary into string""" return ''.join(( chr(int(p, 2)) for p in grouper(8,binary,'') )) 

where the berser comes 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,'') )) 

which allows you to create a temporary list

EDIT since I was selected as the β€œcorrect” answer, I must admit that I used other answers. The point here is not to use a list of generators, but the expression of the generator and iterators

+2
source
 ''.join([ chr(int(p, 2)) for p in wrap(binstr, 8) ]) 

What it does: wrap first breaks your string into pieces 8. Then I repeat each of them and convert it to a whole (base 2). Each converted integer is now covered by the symbol chr . Finally, I complete everything with ''.join to break everything together.

A bit more breakdown of each step chr(int(p, 2)) :

 >>> int('01101010', 2) 106 >>> chr(106) 'j' 

So that it fits into your drawing 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 because it just does the math in place, rather than being repeated through the dictionary again and again. It is also more readable.

+14
source

If execution speed is 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 can create an inverted version similar to this {v:k for k, v in DICO.items()} )

Now you find directly a keyword search, not a loop through the entire dict.

Your new feature will 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 may get some time by changing the way you build the output string (see Effective string concatenation in Python or performance recommendations - string concatenation ). Using join seems promising. I would try: ''.join(DICO_INVERTED.get(b, '') for b in binary)

+3
source

Source: https://habr.com/ru/post/904911/


All Articles