1
def main():

    cc = (input("Enter Message to Encrypt\n"))#user input

    shift = int(2) #shift length

    a=["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"] #reference list

    newa={} #new shifted reference list

    for i in range (0,len(a)):
        newa [a[i]]=a[(i+shift)%len(a)]
        #adds shifted 2 alaphabet into newalaphabet
        #% moodulus used to wrap

        for i in cc: #iterates through cc
            if i in a:
                    a[i]=cc[i]
                    a[i]=newa[i]

main()

So I need input from the user #cc

the shift needs to be two

I used an alphabet list

then shift the alphabet by two to create newa

but I do not know how to apply the new alphabet to my user's input

martineau
  • 119,623
  • 25
  • 170
  • 301
fsauceg
  • 11
  • 2

5 Answers5

0

Iterate through the string cc and replace all the alphabets using the get method of newa. Characters that are not in the dictionary are left as is, by passing them as the default to newa.get when the key is missing:

newa = {}
for i, x in enumerate(a):
    newa[x] = a[(i+shift) % len(a)]

encrypted_text = ''.join(newa.get(i, i) for i in cc)

Python's builtin enumerate can be used in place of range(len(a)) in this case where you need the items in a and their respective indices.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • why do you need the (i,i) in the new.get ? – fsauceg Sep 30 '16 at 00:12
  • That's an alternative way of *getting* a value from a dictionary which will not raise a `KeyError` when the key is not found. Read [Understanding `.get()` method in Python](http://stackoverflow.com/questions/2068349/understanding-get-method-in-python) – Moses Koledoye Sep 30 '16 at 08:26
0

Use mapping for every char, then join them back to create the encrypted message:

''.join(map(lambda x: chr((ord(x) - 97 + shift) % 26 + 97) if x in alphabet else x, cc.lower()))

Integrate it like that:

import string
alphabet = string.ascii_lowercase
cc = input('Enter string to encode: ')
shift = 2 # could be any number

encrypted = ''.join(map(lambda x: chr((ord(x) - 97 + shift) % 26 + 97) if x in alphabet else x, cc.lower()))

cc.lower() for the letters to be all same case (to map using constant ord)

chr((ord(x) - 97 + shift) % 26 + 97) :

  • get the value of the number minus 97 (0 for a, 1 for b, etc.).
  • apply the shift (a turns to c, etc.).
  • modulate by 26 to prevent letters like z from exceeding (25 + 2 = 27, 27 % 26 = 1 = b).
  • add 97 to bring the letter back to ascii standard (97 for a, 98 for b, etc.)

if x in alphabet else x cover for signs that are not letter (if you want to ignore spaces and punctuation use if x in alphabet else '' instead).

Uriel
  • 15,579
  • 6
  • 25
  • 46
0

Use a dictionary to map inputs to outputs

shifted_a = a[-shift:] + a[:-shift]
cipher = {a[i]: shifted_a[i] for i in range(len(a))}
output = ''.join(cipher[char] for char in cc)
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
0

I would just build transition table and use it to decode string.

import string
shift = 2
letters = string.ascii_lowercase + string.ascii_uppercase
transtable = str.maketrans({letters[i]: letters[(i + shift) % len(letters)] 
                            for i in range(len(letters))})

cc = input('Enter string to encode: ')
print(cc.translate(transtable))
Nf4r
  • 1,390
  • 1
  • 7
  • 9
0

I'll throw my solution in there. It should be pretty clear how it works...

import string

index_lookup = {letter: index for index, letter in enumerate(string.ascii_lowercase)}

def caesar_letter(l, shift=2):
    new_index = index_lookup[l] + shift
    return string.ascii_lowercase[new_index % len(index_lookup)]

def caesar_word(s):
    return ''.join([caesar_letter(letter) for letter in s])

I think the above is better for readability but if you're opposed to imports...

index_lookup = {chr(idx): idx - ord('a') for idx in range(ord('a'), ord('z')+1)}

...

In [5]: caesar_word('abcdefghijklmnopqrstuvwxyz')
Out[5]: 'cdefghijklmnopqrstuvwxyzab'
Bruce Pucci
  • 1,821
  • 2
  • 19
  • 26