I’m trying to make a cryptographer. Its essence is to encrypt a word using the Caesar cipher. I know there are many libraries for this, but I tried it myself.
The question is, what is my mistake?
a = 0 # a this is a counter, with each letter change the counter is added one
# ignore case, this is the word that needs to be encrypted
word_crypt = input ("Ce cuvint doresti sa criptezi?") .lower ()
while True:
alphabet = "abcdefghijklmnopqrstuvwxyz" # english alphabet
word_list = list (word_crypt) # make a list from the original word
aa = word_crypt [a] # get the first index string of the original word
bb = alphabet.find (aa) # find this string in the alphabet, get the index
cc = alphabet [bb + 2] # find the letter 2 positions ahead of this letter
a = a + 1 # add 1 counter
if a & gt; = 0: # if counter is greater than or equal to zero
word_new = word_list [word_list.index (aa)] = cc # replace the first letter with +2 in the alphabet
# sort of like making a new line that is equal to the top, this line will be the original word with 1 changed letter
word_list = word_new
list_final = [] # empty list
list_final.append (word_list) # add the replaced letter to this list
# if the counter plus 1 is greater than the length of the word, then we receive the list (cipher word) and stop the loop
elif a + 1 & gt; len (word_crypt):
print (list_final)
break
But, when running the code, it gives such an error on the line with cc = alphabet [bb + 2]
:
Traceback (most recent call last):
File "python", line 26, in & lt; module & gt;
File "python", line 7, in crypt_one
IndexError: string index out of range
According to my logic, this code should work.
Answer 1, authority 100%
In fact, this error is not the only one:
# initially you can do without a counter
a = 0
# this loop can be replaced with `for`
while True:
# the alphabet is set every iteration of the loop, it can be taken out for it
alphabet = "abcdefghijklmnopqrstuvwxyz"
# if we are looking for an index, then we need to use `index`
bb = alphabet.find (aa)
# there is not enough division modulo the length of the alphabet
# so as not to go beyond its borders
cc = alphabet [bb + 2] # this is the reason for the first error
# counter is always greater than or equal to zero
if a & gt; = 0:
# ohohoh, what's here?
word_new = word_list [word_list.index (aa)] = cc
# the list will be reset all the time, even if the program is lucky
# will execute correctly, the output will still only have one character
list_final = []
# this condition will never work,
# this will cause the counter to go out of bounds `word_crypt`
elif a + 1 & gt; len (word_crypt):
I tried to describe all the shortcomings in the comments to the code.
I also add my own version Caesar cipher
class CaesarCipher:
def __init __ (self):
self.alphabet = 'abcdefghijklmnopqrstuvwxyz'
def Encrypt (self, text, shift = 2):
cipher = ''
for ch in text.lower ():
cipher + = self.alphabet [(self.alphabet.index (ch) + shift)% len (self.alphabet)]
return cipher
def Decrypt (self, cipher, shift = 2):
text = ''
for ch in cipher.lower ():
text + = self.alphabet [(self.alphabet.index (ch) - shift)% len (self.alphabet)]
return text
# defaults to 2 letters forward
cipher = CaesarCipher (). Encrypt ("Ce cuvint doresti sa criptezi")
print (cipher) # egbewxkpvbfqtguvkbucbetkrvgak
print (CaesarCipher (). Decrypt (cipher)) # ce cuvint doresti sa criptezi
# because its shift value, for example, 3
cipher = CaesarCipher (). Encrypt ("Ce cuvint doresti sa criptezi", 3)
print (cipher) # fhcfxylqwcgruhvwlcvdcfulswhbl
print (CaesarCipher (). Decrypt (cipher, 3)) # ce cuvint doresti sa criptezi
Answer 2
You in the line bb = alphabet.find (aa)
find the position of the letter in the alphabet, respectively, the variable bb
can take values from 0
to 25
. Let’s say bb = 25
. You in the line cc = alphabet [25 + 2]
refer to the 28th character of the alphabet (which is not present) and you get an overflow of the list. A fix to cc = alphabet [(bb + 2)% 25]
should fix the situation in my opinion.