Converting text to a binary string gives a different binary string than what was used to make the text

Viewed 93

I am creating a simple XOR program in python. The user inputs simple plaintext which is converted to a string of bits. A key is generated of equal length to the plaintext bits, and it is XOR'd. I convert the XOR'd bits back to text and write it as ciphertext. This all works perfectly without issues.

The issue I am having is I want to take that same ciphertext and convert it back to its binary form in preparation for decryption. When I do so, I get a completely different string of bits.

Reproducible example:

import secrets
import sys

def encrypt(plaintext):
    binary_plaintext = [format(x, 'b').zfill(8) for x in bytearray(plaintext, 'utf-8')] # Convert Plaintext to Binary and separates into bytes in a list
    binary_plaintext = "".join(binary_plaintext)                                        # Take list of bytes and join together in one long binary string

    key = key_generator(binary_plaintext) # Create key of 'n' bits where n == len(binary_plaintext)

    ciphertext_binary_string = "".join([str(int(bit1, 2) ^ int(bit2, 2)) for bit1, bit2 in zip(binary_plaintext, key[0])]) # XOR Operation with Key and Plaintext
    ciphertext_binary_bytes = " ".join([ciphertext_binary_string[idex:idex+8] for idex in range(0, len(ciphertext_binary_string), 8)]) # Split the Ciphertext into bytes
    ciphertext = ''.join([chr(int(byte,2)) for byte in ciphertext_binary_bytes.split(" ")]) # Convert Ciphertext to text i.e. ~ýÄÞ$~Ý

    decrypt(ciphertext, key[0], ciphertext_binary_string) # Pass the exact same ciphertext to the decryption

def decrypt(ciphertext, key, previous_ciphertext):
    ciphertext_binary = bin(int.from_bytes(ciphertext.encode('utf-8'), sys.byteorder))
    print(f"{ciphertext_binary[2:]} does not match {previous_ciphertext}")

def key_generator(binary_plaintext):
    integer_key = secrets.randbits(len(binary_plaintext))  # Build a random key that is the same length as the plaintext
    binary_key = bin(integer_key)[2:].zfill(len(binary_plaintext))
    return binary_key, integer_key

encrypt("Hello There")

Essentially there is:

  1. Ciphertext in the form of bits on line 10
  2. Convert this Ciphertext to text on line 12
  3. Pass this same Ciphertext to decryption()
  4. Convert the same Ciphertext back to it's binary format (as we have on line 10) on line 17 text back to bits on line 17.
  5. Line 10 and line 17 do not match. This is what I am trying to understand. Binary > Text > Binary but the two binary forms do not match.

Any insight is appreciated. Thanks

0 Answers
Related