'Python | encrypt string with dictionary

so I have the encrypt dictionary already set up:

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "

word = input("Enter the message: ")
d = {alphabet[i]: encrypt[i] for i in range(len(alphabet))}

and lets say I want to encrypt word, I would use replace()here, but if I use that one, it just replaces everything with A and B.

My code currently looks like that:

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "

d = {alphabet[i]: encrypt[i] for i in range(len(alphabet))}

word = input("Enter a word: ")
 
for key in d.keys():
    word = word.upper().replace(key, d[key])

print(word)

and in the Terminal it prints out "BAAB". Not sure why its only using the A and B and nothing more.



Solution 1:[1]

You can do it with .join():

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQ9RSTUVWXYZAB "
d = {a: e for  a, e in zip(alphabet, encrypt)}
''.join(d[i] for i in 'word'.upper())

Output:

'XQSF'

Solution 2:[2]

You're replacing the letter one by one so the letter a is changed to c but in the next loop, c will be changed to e etc, you only have b and a because it's the 2 last letters in your code and the gap in your code is 2.

You have to use another variable and iterate through the initial variable and add the value letter in another variable from the key in the first variable

Not sure if it's really clear so here's an example :

word2 = ""
for i in word:
  word2 += d[i]

Solution 3:[3]

First you replace every A with C, so you don't have As anymore (only B to Z). Then you replace every B with D, so you don't have Bs anymore, either (only C to Z). Etc. Near the end, you only have Ys and Zs left, and you replace them with A and B, respectively. That's why your output only has As and Bs.

You should make all replacements "in parallel" instead of sequentially like you do, and a proper way to do that is to use str.translate:

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "
trans = str.maketrans(alphabet, encrypt)

word = 'Chaos'
print(word.upper().translate(trans))

Output:

EJCQU

Solution 4:[4]

Something like this should solve it for you:

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
encrypt = "CDEFGHIJKLMNOPQRSTUVWXYZAB "

d = {alphabet[i]: encrypt[i] for i in range(len(alphabet))}

print(''.join([d[i.upper()] for i in input("Enter a word: ")]))

Solution 5:[5]

Adding to @Nin17's answer and assuming the dictionary d is given, you can use map instead of a list comprehension to obtain the string:

res = "".join(map(d.get, "word".upper()))

As NicoCaldo points out, you may also simply add 2 to the ASCII numerical representation of each character, wrapping around and making an exception for the space character .

from_letter = ord("A")
to_letter = ord("Z")
range = to_letter - from_letter
offset = ord("B") - from_letter
res = "".join(map(lambda c: c if c == " " else chr(from_letter + ((ord(c)-from_letter+offset) % range)), "some words".upper()))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nin17
Solution 2 Marius ROBERT
Solution 3 Kelly Bundy
Solution 4 Sefan
Solution 5