So I'm making this code that uses strings to cipher a given phrase with a given key (I can't use the preset functions in python to do it). I believe I've got the idea of how to do it but I;m experiencing this error that I can't figure out how to fix. My code is the following.
def inputForChipher():
input1 = False
input2 = False
while input1 == False:
string = input('Enter the message: ')
input1 = verifyString(string)
while input2 == False:
key = input('Enter the key you want to use: ')
input2 = verifyString(key)
print(cipherWithKey(string, key))
def cipherWithKey(string, key):
string = string.lower()
key = key.lower()
letters = 'abcdefghijklmnopqrstuvwxyz'
count = 0
newCode = ''
for i in string:
if i == '':
count = 0
newCode += i
else:
if count > (len(key)-1):
count = 0
value1 = letters.index(i) + 1
value2 = letters.index(key[count]) + 1
num = value1 + value2
if num > 26:
num -= 26
newCode += letters[num-1]
count += 1
return newCode
And I'm getting the following error:
File "C:\Users\xxxxx\Desktop\funciones.py", line 29, in cipherWithKey
value1 = letters.index(i) + 1
ValueError: substring not found
I know what causes this error, but I'm not sure of why I'm getting it in this case.
well its clear , in your input 'tarea de' you are passing space in your input ( string varible) which is not in letters variable and it fails in that line.
you can add the possible characters to your letters variable like :
letters = 'abcdefghijklmnopqrstuvwxyz '
alternatively you can use string module to provide the full list of whitespaces
import string as st
letters = st.ascii_lowercase + st.whitespace
Related
The encrypt method in my program is not encrypting correctly. I thought I figured out why using debug mode; it's because it reads the spaces between words as something it has to encrypt. So I tried typing a message without spaces but it still didn't come out correctly.
I figure the issue is the if statement with the key. I tried commenting lines out, changing statements, changing the if statement to a for loop, but it still isn't correct.
def main():
vig_square = create_vig_square()
message = input("Enter a multi-word message with punctuation: ")
input_key = input("Enter a single word key with no punctuation: ")
msg = message.lower()
key = input_key.lower()
coded_msg = encrypt(msg, key, vig_square)
print("The encoded message is: ",coded_msg)
print("The decoded message is: ", msg)
def encrypt(msg,key,vig_square):
coded_msg = ""
key_inc = 0
for i in range(len(msg)):
msg_char = msg[i]
if key_inc == len(key)-1:
key_inc = 0
key_char = key[key_inc]
if msg_char.isalpha() and key_char.isalpha():
row_index = get_row_index(key_char,vig_square)
col_index = get_col_index(msg_char,vig_square)
coded_msg = coded_msg+vig_square[row_index][col_index]
else:
coded_msg = coded_msg + " "
key_inc = key_inc+1
return coded_msg
def get_col_index(msg_char, vig_square):
column_index = ord(msg_char) - 97
return column_index
def get_row_index(key_char, vig_square):
row_index = ord(key_char) - 97
return row_index
def create_vig_square():
vig_square = list()
for row in range(26):
next_row = list()
chr_code = ord('a') + row
for col in range(26):
letter = chr(chr_code)
next_row.append(letter)
chr_code = chr_code + 1
if chr_code > 122:
chr_code = ord('a')
vig_square.append(next_row)
return vig_square
main()
This example was given to us:
Enter a multi-word message with punctuation: The eagle has landed.
Enter a single word key with no punctuation: LINKED
The encoded message is: epr oejwm ukw olvqoh.
The decoded message is: the eagle has landed.
But my encoded message comes out as:
epr iloyo sif plvqoh
You have two errors:
First, you don't use all characters in the key. Change the following line:
if key_inc == len(key)-1:
key_inc = 0
to
if key_inc == len(key):
key_inc = 0
Second, you move the key pointer even if you process a non-alpha character in the message (e.g. spaces). Do it only if you encode a character, i.e. make the following change:
if msg_char.isalpha() and key_char.isalpha():
...
key_inc = key_inc+1 # Move this line here
else:
...
Hey guys so I have my program working to a certain extent. My program is suppose to check if there is an "A" in the user input and if done so it will swap that "A" with the next letter.
Here are the examples:
"tan" = "TNA"
"abracadabra" = "BARCADABARA"
"whoa" = "WHOA"
"aardvark" = "ARADVRAK"
"eggs" = "EGGS"
"a" = "A"
In my case this is what works and doesn't work:
Works:
tan to TNA
Doesn't work:
abracadabra = BARCADABAR
whoa = WHO
aardvark = ARADVRA
eggs = EGG
a =
a just equals nothing.
What I'm getting at is that the last character isn't printing and I'm not sure how to do so.
def scrambleWord(userInput):
count = 0
Word_ = ""
firstLetter_ = ""
secondLetter_ = ""
while count < len(userInput):
if count+1 >=len(userInput):
break #copy last character
firstLetter_ = userInput[count] #assigning first letter
secondLetter_ = userInput[count+1] #assigning next letter
if firstLetter_ == 'A' and secondLetter_ != 'A':
Word_ += (secondLetter_ + firstLetter_) #Swap then add both letters
count+=1
else:
Word_+=firstLetter_
count+=1
return Word_
def main():
userInput = input("Enter a word: ")
finish = scrambleWord(userInput.upper())
print(finish)
main()
Probably because you are just breaking without writing the userinput[count] into the word.
if count+1 >=len(userInput):
Word_ += userInput[count]
break #copy last character
This should help
I'm currently making an encryption program for an assignment however I cannot decrypt. The cause of this is that the key is a string made from a randomly generated bitstring however when turning the key back into a bitstring I get a different bitstring. I realized this after checking and finding out that the bitstring after turning the key back to binary is shorter than the bitstring used to make the key.
##imports##################################################
from socket import *
import random
##functions################################################
def CCipher(message, k):
output = ""
for x in message:
i = ord(x)
i = (i+k)%128
output += chr(i)
return output
def toBinary(message):
output = ""
for x in message:
i = bin(ord(x))[2:]
output += i
return output
def XOR(bitstring1, bitstring2):
output = ""
if(len(bitstring1) != len(bitstring2)):
print("Use bitstrings of the same length")
return None
for x in range(len(bitstring1)):
if(bitstring1[x] == "1" and bitstring2[x] == "0"):
output += "1"
elif(bitstring1[x] == "0" and bitstring2[x] == "1"):
output += "1"
else:
output += "0"
return output
def randomBinary(k):
output = ""
for x in range(k):
i = random.randint(0,1)
output = output + str(i)
return output
def toString(message):
output = ""
i = ""
n = 0
for x in message:
n += 1
i += x
if(n == 7):
output += chr(int(i,2))
n = 0
i = ""
return output
##server stuff#########################################
serverName = "OmariPC"
serverPort = 12347
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
##files################################################
nowar = open("NoWar.dat",'r')
trump = open("Trump.dat","w")
##encryption###########################################
message = nowar.read()
mesBin = toBinary(message)
bkey = randomBinary(len(mesBin))
encrypted = XOR(mesBin, bkey)
encrypted = toString(encrypted)
key = toString(bkey)
trump.write(encrypted)
trump.close()
enKey = CCipher(key, 4)
##sending###############################################
clientSocket.send(enKey.encode())
print(len(enKey))
clientSocket.send(encrypted.encode())
print(len(encrypted))
##testing###############################################
if key == toString(bkey):
print(True)
else:
print(False)
if len(toBinary(key)) == len(bkey):
print(True)
else:
print(False)
output:
168
168
True
False
def toBinary(message):
output = ""
for x in message:
i = bin(ord(x))[2:]
output += i
return output
bin(ord(x)) generates strings of variable length. For example:
>>> bin(ord(' '))
0b100000
>>> bin(ord('a'))
0b1100001
You concatenate all of the results of bin() together, so there's no way to separate them later. Meanwhile, your toString() function reads exactly 7 "bits" at a time.
You could make bin() append chunks of a fixed-size instead:
# Pad the left with 0s to always generate a string of length 7.
# (Assumes that all input characters are ASCII.)
assert(ord(x) < 128)
bin(ord(x))[2:].rjust(7, '0')
I want to get specific values from a for loop to add to another string to create a vigenere cipher.
here's the code.
userinput = input('enter message')
keyword = input('enter keyword')
new = ''
for a in keyword:
pass
for i in (ord(x) for x in userinput):
if 96 < i < 123: #lowercase
new += chr(97 + (i+ord(a)-97)#keeps all values in alphabet
print(new)
so the answer i want if i do 'abcd' as my message and 'ab' as my keyword the desired outcome is 'bddf' as 'a' + 'a' is 'b' and 'b' + 'b' = 'd' and etc. how would i change the code to match my desired outcome or will i have to change it completely and how would i go about doing so.
try this (you are missing the mod 26-part):
from itertools import cycle
plaintext = input('enter message: ')
keyword = input('enter keyword: ')
def chr_to_int(char):
return 0 if char == 'z' else ord(char)-96
def int_to_chr(integer):
return 'z' if integer == 0 else chr(integer+96)
def add_chars(a, b):
return int_to_chr(( chr_to_int(a) + chr_to_int(b) ) % 26 )
def vigenere(plaintext, keyword):
keystream = cycle(keyword)
ciphertext = ''
for pln, key in zip(plaintext, keystream):
ciphertext += add_chars(pln, key)
return ciphertext
ciphertext = vigenere(plaintext, keyword)
print(ciphertext)
if you like list comprehensions, you can also write
def vigenere(plaintext, keyword):
keystream = cycle(keyword)
return ''.join(add_chars(pln, key)
for pln, key in zip(plaintext, keystream))
UPDATE
updated according to the wish that a+a=b. note that z is in that case the neutral element for the addition (z+char=z).
I recently began to play around with cryptography after playing with Project Euler Problem 59, and I made a basic XOR cryptography system. In this case the concatentation of your output and a random key are made and saved to a text file (only as a test, I will make it better once I've fixed this bug), but I've noticed that certain messages do not encrypt or decrypt correctly. I've narrowed this down to messages of length > 54. My code is as follows:
#encrypt.py
import random
msg = raw_input("Enter your message: ")
out = ""
key = ""
for i in xrange(len(msg)):
key += chr(random.randint(0,255))
k = 0
for char in msg:
out += chr(ord(msg[k]) ^ ord(key[k]))
k += 1
print "\nYour output is:", out
print "Your key is:", key
raw_input()
with open("output.txt","r+") as f:
f.truncate()
f.write(out+key)
And decryption:
#decrypt.py
import sys
if not len(sys.argv) > 1: exit()
with open(sys.argv[1],"r+") as f:
content = f.read()
msg, key = content[:len(content)/2], content[len(content)/2:]
out = ""
k = 0
for char in msg:
out += chr(ord(char) ^ ord(key[k]))
k += 1
print out
raw_input()
For longer messages (than 54 chars), when they are decrypted they will give a string of random characters. Does anyone have an idea as to why this happens?
Since making characters out of random bits is likely to produce characters that look ugly on the screen, you can try hex-encoding the output before printing it.
#encrypt.py
import random
msg = raw_input("Enter your message: ")
out = ""
key = ""
for i in xrange(len(msg)):
key += chr(random.randint(0,255))
k = 0
for char in msg:
out += chr(ord(msg[k]) ^ ord(key[k]))
k += 1
out = ":".join("{:02x}".format(ord(c)) for c in out)
key = ":".join("{:02x}".format(ord(c)) for c in key)
print "\nYour output is:", out
print "Your key is:", key
raw_input()
with open("output.txt","w+") as f:
f.truncate()
f.write(out+key)
Then for decryption, you have to remove the colons and hex-decode before you can continue with regular decryption.
#decrypt.py
import sys
if not len(sys.argv) > 1: exit()
with open(sys.argv[1],"r+") as f:
content = f.read()
content = content.replace(':', '')
msg, key = content[:len(content)/2], content[len(content)/2:]
msg = msg.decode('hex')
key = key.decode('hex')
out = ""
k = 0
for char in msg:
out += chr(ord(char) ^ ord(key[k]))
k += 1
print out
raw_input()
At the console, the results look like this:
$ python encrypt.py
Enter your message: onetwothreefourfivesixseveneightnineteneleventwelvethirteen
Your output is: 7f:09:d0:8c:2e:1a:e0:a0:84:e7:bf:3b:e8:cc:f3:4e:35:e4:4f:20:c8:00:72:9d:f0:bc:de:54:88:30:a6:3d:93:3f:c1:6d:46:4a:68:ca:96:2e:16:50:43:0f:30:fa:27:f3:f2:8d:35:4b:6a:11:cc:02:04
Your key is: 10:67:b5:f8:59:75:94:c8:f6:82:da:5d:87:b9:81:28:5c:92:2a:53:a1:78:01:f8:86:d9:b0:31:e1:57:ce:49:fd:56:af:08:32:2f:06:af:fa:4b:60:35:2d:7b:47:9f:4b:85:97:f9:5d:22:18:65:a9:67:6a
$ cat output.txt
7f:09:d0:8c:2e:1a:e0:a0:84:e7:bf:3b:e8:cc:f3:4e:35:e4:4f:20:c8:00:72:9d:f0:bc:de:54:88:30:a6:3d:93:3f:c1:6d:46:4a:68:ca:96:2e:16:50:43:0f:30:fa:27:f3:f2:8d:35:4b:6a:11:cc:02:0410:67:b5:f8:59:75:94:c8:f6:82:da:5d:87:b9:81:28:5c:92:2a:53:a1:78:01:f8:86:d9:b0:31:e1:57:ce:49:fd:56:af:08:32:2f:06:af:fa:4b:60:35:2d:7b:47:9f:4b:85:97:f9:5d:22:18:65:a9:67:6a
$ python decrypt.py output.txt
onetwothreefourfivesixseveneightnineteneleventwelvethirteen