Hello.

I am was doing research on cryptography and found a simple algorithm (One time pad algorithm) that interests me.
I was able to create a simple version of this that only works with capital letters. The problem however is that the encrypted contents doesn't only contain capital letters. It somethimes contain a special character like ?.

Here is my code:

import random

class otp:
    def __init__(self):
        self.key = ""
        self.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"


    """
        Generate the key.
        The key is a random generated of alphabetical characters.
        The key is the same length as the message.
    """
    def generate_key(self, messagelength):

        # Get the random characters from the alphabet.
        for index in range(messagelength):
            self.key += self.alphabet[random.randint(0, len(self.alphabet) - 1)]


    """
        Returns the key so that the user can use it if required.
    """
    def get_key(self):
        return self.key


    """
        Encrypt the message.
        Add each character value of the key to each character value of the message.
        To get the key and character value, subtract 64 from the ordinal value of the character in capital form.
    """
    def encrypt(self, message):
        ciphertext = ""

        # Generate the key.
        self.generate_key(len(message))

        # Encrypt the message.
        for index in range(len(message)):        
            messagechar = ord(message[index]) - 64
            keychar = ord(self.key[index]) - 64
            subchar = (messagechar + keychar) % 26 - 1
            ciphertext += chr(subchar + 64)

        return ciphertext

    """
        Decrypt the message.
        Subtreact each character value of the key from the message character value.
        To get the key and character value, subtract 64 from the ordinal value of the character in capital form.
    """
    def decrypt(self, message):
        plaintext = ""

        # Decrypt the message.
        for index in range(len(message)):
            messagechar = ord(message[index]) - 64
            keychar = ord(self.key[index]) - 64
            addchar = (messagechar - keychar) % 26 + 1
            plaintext += chr(addchar + 64)

        return plaintext


if __name__ == '__main__':
    o = otp()

    enc = o.encrypt("ABCDE")
    print("Encrypted: " + enc)
    dec = o.decrypt(enc)
    print("Decrypted: " + dec)

Sample output:

Encrypted: IEEMK
Decrypted: ABCDE

Encrypted: LHLAE
Decrypted: ABCDE

Encrypted: UMS?L
Decrypted: ABCDE

As you can see the third time it encrypted the word HELLO there was an ? in the string. I need to make it that there are only capital letters.

I would Recommend you look into how ASCII coding of characters works, it will make things like this a lot easier. also, I would recommend you look into the uppercase and lowercase functions.

Also when you do the encrypt function, you can do something more like:

chars = list(message)
for c in chars: 
    ...
    ...

This takes care of iterating over each character exactly once, and saves having to screw around with indexing into arrays.

which you can use the int function to get the ascii codes, and simplify a lit more.

Also,... when you do any kind of user input for this, dont forget to strip off any trailing newlines before processing the text.

I did look at how ASCII coding work. But I cant figure out whats wrong in my code that it displays the other characters.

This question has already been answered. Start a new discussion instead.