Python Forum
Vigenere and Caesar Cipher
Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Vigenere and Caesar Cipher
#1
I am trying to code in python using a caesar and a vigenere cipher so the user can pick which one they want to use and encrypt or decrypt. I have coded the caesar but really struggling with the vigenere can anyone please help as im lost with this.
Thanks
def caesar(message, shift):
    message = message.lower()
    secret = ""
    for c in message:
        if c in "abcdefghijklmnopqrstuvwxyz":
            num = ord(c)
            num += shift
            if num > ord("z"):
                num -= 26
            elif num < ord("a"):
                num += 26
            secret = secret + chr(num)
        else:
            secret = secret + c
    return secret



def encrypt(message):
    return caesar(message, 5)

def decrypt(message):
    return caesar(message, -5)



msg = input("Your message to Encrypt? Hit Enter to Decrypt ")
if len(msg) > 0:
    secret = encrypt(msg)
    print("The encoded message is:", secret)
else:
    secret = input("Your message to decode? ")
    if len(secret) > 0:
        msg = decrypt(secret)
        print("The decoded message is:", msg)
Reply
#2
You should split your problem into smaller problems. First you should have a function which shifts one char:

import string


def shift_char(char, n=13):
    if len(char) != 1:
        raise ValueError('String must be size of 1')
    if not isinstance(char, str):
        raise ValueError('Input must be a str')
    if char.lower() in string.ascii_lowercase:
        idx = string.ascii_lowercase.index(char.lower())
        idx += n
        idx %= len(string.ascii_lowercase) # look for modulo operation, what this does
        # it's often very handy for operations like this one
    else:
        return char
    if char.islower():
        return string.ascii_lowercase[idx]
    else:
        return string.ascii_uppercase[idx]
Output:
>>> shift_char('H') 'U' >>> shift_char('H', 2) 'J' >>> shift_char('Z', 1) # begins shifts one to right and begins at the beginning of the list 'A' >>> shift_char('H', 1337) 'S'
A str is also iterable. You can do the classic for loop to iterate over every single character of the str object and append it to a list or you just use the built-in map function for this task:

map_object = map(shift_char, 'Hello World!')
# first argument is the function, the second is an iterable.
# Each element of the iterable is called with the function shift_char
# shift_char('H'), shift_char('e'), shift_char('l'), ...
Since Python 3 the map function returns an lazy evaluated generator object.
Output:
>>> map_object <map at 0x7f6a1430f710>
So you need a function to iterate over it. You can use a for loop to iterate over the map object or list or tuple or put it as an argument into the join method of str:
for c in map_object:
    print(c)

# now the map object is exhausted. If you want to use it more than once, you've to create a new one
map_object = map(shift_char, 'Hello World!')

# now demonstration of the join method of the class str
''.join(map_object) # iterates over map_object and join between them '' == str of len 0
# you can also write this as str.join('', map_object)

# now you want to set the keyword argument n. You can do this with the partial function from functools
from functools import partial


shift10 = partial(shift_char, n=10)
# first argument is the function itself, and n is the keyword argument of shift_char
# we create the map_object:
map_object = map(shift_char, 'Hello World!')
# and then using the join method
encoded_text = ''.join(map_object)

# or compact writing:
print(''.join(map(shift10, 'Hello World!')))

# make a function for this task

def encode(text, n):
    shift_func = partial(shift_char, n=n)
    return ''.join(map(shift_func, text))
Now make the test:
text = 'Hello World 123 !!!'
encoded = encode(text, 13)
decoded = encode(encoded, 13)

print(text)
print(encoded)
print(decoded)
print(text == decoded)
You should see:
Output:
Hello World 123 !!! Uryyb Jbeyq 123 !!! Hello World 123 !!! True
Now think about it how to extend the shift_char function, to modify numbers and maybe punctuation as well.
You can find it in string.digits and string.punctuation. Use the length of them for the modulo operation (%).

Hopefully this was not too much.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Ceaser cipher program oli_action 5 2,816 Sep-14-2020, 10:43 AM
Last Post: oli_action
  Cipher Caesar Azilkhan 1 2,116 Nov-21-2019, 03:40 PM
Last Post: ichabod801
  No idea how to use the Caesar Cypher in my code celtickodiak 5 3,018 Oct-08-2019, 03:29 AM
Last Post: stullis
  Monoalphabetic cipher pawlo392 1 12,677 Apr-01-2019, 08:51 PM
Last Post: ichabod801
  Caesar cipher Drone4four 19 10,520 Nov-11-2018, 04:07 AM
Last Post: nilamo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020