I found code that converts a string to numbers, when I run the code in the terminal via python3, it gives an error:

Traceback (most recent call last): File "test.py", line 49, in <module> numberOutput = int(bit_list_to_string(string_to_bits(inputString)),2) #1976620216402300889624482718775150 File "test.py", line 31, in string_to_bits map(chr_to_bit, s) File "test.py", line 30, in <listcomp> return [b for group in File "test.py", line 29, in chr_to_bit return pad_bits(convert_to_bits(ord(c)), ASCII_BITS) File "test.py", line 14, in pad_bits assert len(bits) <= pad AssertionError 

When I run the program through Python (it is version 2.7), the code works correctly.

Code:

 BITS = ('0', '1') ASCII_BITS = 8 def bit_list_to_string(b): """converts list of {0, 1}* to string""" return ''.join([BITS[e] for e in b]) def seq_to_bits(seq): return [0 if b == '0' else 1 for b in seq] def pad_bits(bits, pad): """pads seq with leading 0s up to length pad""" assert len(bits) <= pad return [0] * (pad - len(bits)) + bits def convert_to_bits(n): """converts an integer `n` to bit array""" result = [] if n == 0: return [0] while n > 0: result = [(n % 2)] + result n = n / 2 return result def string_to_bits(s): def chr_to_bit(c): return pad_bits(convert_to_bits(ord(c)), ASCII_BITS) return [b for group in map(chr_to_bit, s) for b in group] def bits_to_char(b): assert len(b) == ASCII_BITS value = 0 for e in b: value = (value * 2) + e return chr(value) def list_to_string(p): return ''.join(p) def bits_to_string(b): return ''.join([bits_to_char(b[i:i + ASCII_BITS]) for i in range(0, len(b), ASCII_BITS)]) inputString = "attack at dawn" numberOutput = int(bit_list_to_string(string_to_bits(inputString)),2) #1976620216402300889624482718775150 bitSeq = seq_to_bits(bin(numberOutput)[2:]) #[2:] is needed to get rid of 0b in front paddedString = pad_bits(bitSeq,len(bitSeq) + (8 - (len(bitSeq) % 8))) #Need to pad because conversion from dec to bin throws away MSB's outputString = bits_to_string(paddedString) #attack at dawn 

What adjustments should be made to make the code work properly?

  • Sorry if not the topic. Did not try to use the built-in module decimal - Decimal fixed point and floating point arithmetic - Lecron
  • And what does the code do? We watched at what point the behavior of the code starts to differ from that of py2? - gil9red
  • The problem was in the division in the ef function convert_to_bits (n), as a result of this work of the function, a list of real numbers is obtained. Thank you all for the answers! - Gabriel Mignola

1 answer 1

Rewrote the algorithm, look:

 ASCII_BITS = 8 def bins_str(text): def to_bin(c): return bin(ord(c))[2:].zfill(ASCII_BITS) return ''.join(to_bin(c) for c in text) # 1976620216402300889624482718775150 inputString = "attack at dawn" bin_str = bins_str(inputString) print(bin_str) # 0110000101110100011101000110000101100011011010110010000001100001011101000010000001100100011000010111011101101110 print(int(bin_str, 2)) # 1976620216402300889624482718775150 

And the inverse algorithm:

 def int_to_text(number): bin_str = bin(number)[2:] pad = '0' * (ASCII_BITS - len(bin_str) % ASCII_BITS) bin_str = pad + bin_str chars = [] for i in range(0, len(bin_str), ASCII_BITS): bin_part = bin_str[i: i + ASCII_BITS] c = chr(int(bin_part, 2)) chars.append(c) return ''.join(chars) print(int_to_text(1976620216402300889624482718775150)) # attack at dawn 

Ps.

  • ord(...) - returns the character code
  • bin(...) - returns a string in binary representation with the prefix 0b
  • bin(...)[2:] - returns a new line starting with the third character
  • ....zfill(8) - returns a new line, complementing the missing 0 on the left
  • ''.join(... - combines elements into a single line, i.e., concatenation

Clearly:

 print(ord('A')) # 65 print(bin(ord('A'))) # 0b1000001 print(bin(ord('A'))[2:]) # 1000001 print(bin(ord('A'))[2:].zfill(8)) # 01000001