Reputation: 775
I am writing an algorithm to encrypt and decrypt using a key. or rather I have, this is more of a rewrite to organise my code. Anyway I just started to build a text based interface, Tkinter will come later.
When indexing a Key, which I have been setting to something like 12345 I get an "IndexError: string index out of range". I know what this means. But I also know that the whole string is being indexed in a loop. starting at 0. This is where it gets the error. Ive even tried testing it seperately e.g. print(Key[0]) But Python still throws an error. I dont understand why. It is referencing the string 12345 with 0, which should return 1.
Do you want to encrypt or decrypt? encrypt
Input a string toencrypt- Hello123
Input a key- 12345
123451
1234512
12345123
Key =
Traceback (most recent call last):
File "C:\Users\Theo_2\Google Drive\Computer science\Encryption and decryption work\Cipher 2\Cipher 2.5.0 Beta .py", line 142, in <module>
User_text_interface(True)
File "C:\Users\Theo_2\Google Drive\Computer science\Encryption and decryption work\Cipher 2\Cipher 2.5.0 Beta .py", line 137, in User_text_interface
print(str(Encrypt(User_input)))
File "C:\Users\Theo_2\Google Drive\Computer science\Encryption and decryption work\Cipher 2\Cipher 2.5.0 Beta .py", line 27, in Encrypt
print(Key[0])
IndexError: string index out of range
For reference here is my code:
Specifically I think my problem is in the Encrypt
function, although it may well be in Decrypt
as well. Please ignore the commented out stuff in the middle, I was running every value through a loop of encryption and decryption which worked fine
import time, sys
Master_Key = "0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#£$%&'()*+,-./:;?@[\\]^_`{|}~\t\n\r\x0b\x0c"
global Output
Output = ""
global Key
Key = ""
##global User_input
def Compatibility_check(Key, User_input):
Temp = 0
while Key == "":
print("Your key cannot be blank")
Key = input("Please input a new key: ")
while len(Key) > len(User_input):
Key = Key[:-1]
while len(Key) < len(User_input):
Key += (Key[Temp])
Temp += 1
print(Key)
def Encrypt(User_input):
##Compatibility_check(Key)
Count = 0
global Output
Output = ""
while Count < len(User_input):
print(Key[0])
print("Count = " + str(Count))
print("Key count = " + str(Key[Count]))
print("Master_key.index")
print("Testing- Input indexer- " + str(Master_Key.index(User_input[Count])))
print("Testing- Key indexer- " + str(Master_Key.index(Key[Count])))
ref_for_output = Master_Key.index(User_input[Count]) + Master_Key.index(Key[Count])
if ref_for_output >= len(Master_Key): ## As [] starts from zero
ref_for_output -= len(Master_Key)
Output += Master_Key[ref_for_output]
Count += 1
##print("Output is " + Output)
return Output
def Decrypt(User_input):
##Compatibility_check(Key)
Count = 0
global Output
Output = ""
while Count < len(User_input):
ref_for_output = Master_Key.index(User_input[Count]) - Master_Key.index(Key[Count])
if ref_for_output < 0:
ref_for_output += len(Master_Key)
Output += Master_Key[ref_for_output]
Count += 1
##print("Output is " + Output)
return Output
def Test_algorithm(Null):
Counter1 = 0
while Counter1 < (len(Master_Key)-1): ##If <= doesnt work use (len(Master_Key)-1)
Input, Counter2 = Master_Key[Counter1], 0
print("Input = " + Input)
Counter1 += 1
print("Loop 1")
if Counter1 == len(Master_Key):
print("The program works.")
while Counter2 < (len(Master_Key)-1):
global Key
Key = Master_Key[Counter2]
Encrypt(Input)
##Temp = Output
Decrypt(Output)
print("Encryption and decryption of Input- " + str(Input) + " with the Key- " + str(Key) + " results in an output of " + str(Output))
if Input == Output:
print("Pass")
else:
print("Fail")
sys.exit
Counter2 += 1
##Counters are used here, it is simply easier to use a counter and a while loop when dealing with references from a for loop
def User_text_interface(Repeat):
while Repeat == True:
ED = input("Do you want to encrypt or decrypt? ")
User_input = input("Input a string to" + str(ED) + "- ")
Key = input("Input a key- ")
Compatibility_check(Key, User_input)
if ED.lower() == "encrypt" or ED.lower() == "e":
print(str(Encrypt(User_input)))
elif ED.lower() == "decrypt" or ED.lower() == "d":
print(str(Decrypt(User_input)))
User_text_interface(True)
Upvotes: 0
Views: 655
Reputation: 775
Turns out my problem was obvious. It was in the way I had written my compatibility check function. Basically It took two inputs, Key and User_input. So it was supposed to check Key for a variety of things and change it if it didn't meet them. Unfortunately I had overlooked the fact that it was just changing its internal variable 'Key', which has the same name as the 'Key' being used later.
This meant that the Key was shorter than the input, and my encrypt function tried to reference a character in Key which didn't exist.
Upvotes: 0
Reputation: 1121486
Your Key
variable is an empty string:
>>> Key = ''
>>> Key[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
That's because you are never changing the global Key
variable, only a local. global
statements must be put in the function:
def Compatibility_check(Key, User_input):
global Key
Temp = 0
while Key == "":
print("Your key cannot be blank")
Key = input("Please input a new key: ")
while len(Key) > len(User_input):
Key = Key[:-1]
while len(Key) < len(User_input):
Key += (Key[Temp])
Temp += 1
print(Key)
but it'd be better to have the function return the new value; you'd use return Key
(ending the function) then assign that return value:
Key = Compatibility_check(Key, User_input)
Upvotes: 2