Search code examples
pythonencryptionkeycaesar-cipher

Why is there a %26 (Python)?


I am trying to decipher a text from user without knowing the key in caesar cipher.

I probably understand most of it but I don't get it why they use the mod 26 on line 8



alphabet=['a','b','c','d','e','f','g','h','i','j','k','l','m',
    'n','o','p','q','r','s','t','u','v','w','x','y','z']
print('write the message you want to decode?')
inputString = input()
inputString = inputString.lower()

transAlphabet = {}

def createDict(shift):
    for i in range(0,26):
        letter = alphabet[i]

        transAlphabet[letter]=alphabet[(i+shift)%26]


def encodeMessage(message):
    cypherText = ''
    for letter in message:
        if letter in transAlphabet:

            cypherText = cypherText + transAlphabet[letter]
        else:
            cypherText = cypherText + letter
    print(cypherText)

for i in range(0,26):
    createDict(i)
    encodeMessage(inputString)



Please would be really helpful if someone helps me out thank you!


Solution

  • The modulo %26 is to make the alphabet circular, when you're at z come back at a

    Example for alph[(i + shift) % 26] with i=20 and shift=10

    • without modulo you'll like to reach index 30 in the array and it doesn't not exist
    • with modulo you'll reach index 30%26 = 4 in the array, letter e

    But also your algo is a bt strange, I would have done the shifting on the fly for each car, but your solution may be more efficient for long text as you don't need to compute the shift everytime.

    Not computing the shifted alphabet before would look like this

    from string import ascii_lowercase
    alphabet = ascii_lowercase
    
    def encode_message(message, shift):
        cypher_text = ''
        for letter in message:
            letter_idx = alphabet.index(letter)
            cypher_text = cypher_text + alphabet[(letter_idx + shift) % 26]
        return cypher_text
    
    def decode_message(message, shift):
        cypher_text = ''
        for letter in message:
            letter_idx = alphabet.index(letter)
            cypher_text = cypher_text + alphabet[(26 + letter_idx - shift) % 26]
        return cypher_text