elif chosenA == 2:
print('''You have chosen to decrypt a message,''')
print("Please enter the name of the file you wish to decrypt")
a = raw_input()
with open(a + '.txt') as text:
lar = text.read()
print(lar)
MS = 0
print("oi drongo enter ya key")
b = raw_input()
for c in b:
f = ord(c)
MS = MS + f
geek = (MS / 8) - 32
#print(geek)
nlar = ''
for c in lar:
g = ord(c)
if g > 126:
g -= 94
g -= geek
f = unichr(g)
print(f)
During the "for c in lar:" I am trying to get the characters in the file to be converted to ascii values using ord() and then if they are greater than 126 (the alphabet) remove 94 from the value then take geek(the offset factor generated from an 8 character key) away from the ascii value so it will be returned to text that was originally encrypted, if you want the full code just say and I'll provide it if it will help.
Related
I have an assignment for a lab that asks me to decrypt an input file that has been encrypted with a ceasar cipher. As background, my instructor has already let everyone know that the cipher has a shift distance of three.
I was able to get my to write to an output file, but my output.txt is completely unreadable, and not close at all to what the expected output should be. I remember my instructor mentioning that we could use ord() and chr() combined with arithmetic to transform the encoded characters to plaintext.
decode = inpf.readlines()
for line in decode:
output = ""
c = str()
for c in line:
if c >= "a" and c <= "z":
x = ord(c)
x += 23
x %= 26
y = chr(x)
output = output + y
if c >= "A" and c <= "Z":
x = ord(c)
x += 23
x %= 26
y = chr(x)
output = output + y
else:
output = output + c
outf.write(output + "\n")
I appreciate any help or advice you can offer! Thanks!!
EDIT:
Sample Input: "Wkh Orug Ri Wkh Ulqjv:"
Output: " :"
Expected Output: "The Lord Of The Rings:"
The ord() method in Python converts a character into its Unicode code value. Capital 'A' starts from unicode 65 and small 'a' from 97. Also you should use 'elif' instead of second 'if' statement. Otherwise, in case of a small letter, the letter will repeat. You need to get the letters position in alphabet, apply the shift and convert it back to unicode. A working example of your code is given below:
inpf = open("input.txt",'r')
outf = open("output.txt",'w')
decode = inpf.readlines()
for line in decode:
output = ""
c = str()
for c in line:
if c >= "a" and c <= "z":
x = ord(c) - 97 #small a
x -= 3
x = (x+26)%26 #For handling negative numbers
y = chr(x + 97)
output = output + y
elif c >= "A" and c <= "Z":
x = ord(c) - 65 #Capital A
x -= 3
x = (x+26)%26 #For handling negative numbers
y = chr(x + 65)
output = output + y
else:
output = output + c
outf.write(output + "\n")
This coding exercise is giving me a lot of trouble and I need help.
Here is the problem.
Write a program which does the reverse of the example above: it should
take a character as input and output the corresponding number (between
1 and 26). Your program should only accept capital letters. As
error-checking, print invalid if the input is not a capital letter.
Here is what I have so far.
inp = input()
if (len(inp) > 1 or inp != inp.upper()):
print("invalid input")
else:
print(ord(inp)-ord("A")+1)
letter = input()
if letter>='A' and letter<='Z':
print(int(ord(letter))-64)
else:
print('invalid')
As clarified in the comment, the problem appears to be that the validation doesn't cover enough cases.
To check that the number you calculate is a valid upper-case character you could just check if it is between 1 and 26:
if 1 < ord(inp) - ord("A") + 1 < 26:
print(ord(inp) - ord("A") + 1)
else:
print("Invalid input")
To add this to your current validation:
inp = input()
if (len(inp) > 1 or inp != inp.upper() or
ord(inp) - ord("A") + 1 < 1 or ord(inp) - ord("A") + 1 > 26):
print("invalid input")
else:
print(ord(inp)-ord("A")+1)
This might help you out.
Add whatever you want to test to the test_data list.
# take advantage of the string module to get a string of all upper-case characters
from string import ascii_uppercase # equiv of 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
test_data = ['z', 'AB', '', 10, None, "#", *ascii_uppercase] # some test data including all the upper-case characters
for item in test_data:
string = str(item) # turn the item into type str
length_is_one = len(string) == 1 # get the length
if all((length_is_one, string in ascii_uppercase)): # if all these are true
print(ascii_uppercase.index(item) + 1) # print the index of the letter + 1
else:
print(f'"{item}" is {INVALID}') # I modified the invalid output
OUTPUT:
"z" is invalid
"AB" is invalid
"" is invalid
"10" is invalid
"None" is invalid
"#" is invalid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
I am trying to make a cryptography program.
When I run this program and insert for example abc with shift 2 it will return cde which is good. But I tried to insert xyz aswell with shift 3 and instead of shifting correctly abc it returns aaa. This also happens if I use shift 2 then it returns zaa.
How can I adjust my program to correctly start from the beginning when the alphabet is done with the ASCII tabel?
shift = int(input("Please insert a number you want to shift the characters with: "))
end = ""
for x in alf:
ascii = ord(x)
if ascii >= 97 and ascii <= 122:
res = ascii + shift
if res > 122:
res = 0 + 97
min = res + shift
end = end + chr(min)
print (end)
It is because your logic expression is wrong. Here is an example that will allow any positive integer as right shift, beginning again at a again. And it can be very much optimized (hint: use modulo operator), but this is with minor changes to your code and numerics written out loud.
for x in alf:
ascii = ord(x)
if ascii >= 97 and ascii <= 122:
res = ascii + shift
while res > 122:
res = res - (122 - 97) - 1
end = end + chr(res)
In a ceasar cipher I need it to be that my upper characters remain upper and that non letter character remain non letters/the same. I have it that I can work with lower letters.
Upper letters however are converted to lower and a different letter. Non-letter characters are converted to a lower letter as well. Upper letters must shift but remain upper. Non-letter characters must remain as non-letter character.
p = raw_input(("enter a word"))
n = input(("how many must it shift"))
a = 0
b = 0
c = 0
d = 0
for i in p:
if i.isupper():
a += 1
elif i.islower():
b += 1
elif i.isdigit():
c += 1
else:
d += 1
e = ""
for i in p:
if i == "":
e += i
else:
integerValue = ord(i)
integerValue-= 97
integerValue += n
integerValue %= 26
integerValue += 97
e += chr(integerValue)
print e
You can use i.isalpha() to check if the current character is a letter or not and you can use i.isupper() to check if the current letter is uppercase or not. When you convert the letter you will need to make the letter lowercase and then convert it back to upper. On top of those changes you have too many parenthesis for your inputs. I used raw_input since I'm using python 2.7. Your formatting is so off your code that's posted won't run due to indentation errors and your line if i == "" checks for an empty string instead of a space which I am assuming you were going for. All that said here is what I did to your code to try and keep it similar to what you had while cutting out extraneous bits.
p = raw_input("enter a word")
n = int(raw_input("how many must it shift"))
e = ''
for i in p:
if not i.isalpha():
e+=i
else:
integerValue = ord(i.lower())
integerValue-= 97
integerValue += n
integerValue %= 26
integerValue += 97
if i.isupper():
e += chr(integerValue).upper()
else:
e += chr(integerValue)
print e
I'm trying to add together strings where each letter has been converted to ASCII and then added together accordingly. So for example, adding together the strings "goodbye" "hello" I'd like to convert each letter to ascii then add them together like so:
103 + 104 (g + h)
111 + 101 (o + e)
111 + 108 (o + l)
100 + 108 (d + l)
98 + 111 (b + o)
121 + 104 (y + h)
101 + 101 (e + e)
In this instance, "goodbye" must be interchangeable, i.e. user inputted. This is the code I've generated so far:
input1 = input("Enter word: ")
input2 = "goodbye"
l = len(upnumber)
count = 0
for i in (input1):
x = (ord(i))
while count <= l:
for j in (input2):
y = (ord(j))
total = (x + y)
count = count + 1
print (total)
This code doesn't work. It just seems to add the first character of input1 to every character in input2, an innumerate amount of times.
The count is in there as I'd like the loop to stop after each character in input1 has been added to the loop of input2.
You are looping over all of input2 for each character in input1, because you nested the loops.
Use the zip() function instead to pair up letters:
input1 = input("Enter word: ")
input2 = "goodbye"
# make input1 at least as long as input2
while len(input1) <= len(input2):
input1 += input1
for x, y in zip(input1, input2):
total = ord(x) + ord(y)
print(total)
where zip() will stop iterating once the shortest of the two strings is done. Since input1 has been extended to repeat until it is at least as long as input2, that means you end up processing all characters of input2, and no more, unless input1 was longer to start with.
Instead of manually repeating input2, you can also use itertools.cycle() to cycle through all characters in input1 indefinitely:
from itertools import cycle
input1 = input("Enter word: ")
input2 = "goodbye"
for x, y in zip(cycle(input1), input2):
total = ord(x) + ord(y)
print(total)
Demo of the latter approach, with some extra formatting to illustrate what is going on:
>>> from itertools import cycle
>>> input1 = 'hello'
>>> input2 = "goodbye"
>>> for x, y in zip(cycle(input1), input2):
... total = ord(x) + ord(y)
... print('{!r} + {!r} = {:3d} + {:3d} = {:3d}'.format(x, y, ord(x), ord(y), total))
...
'h' + 'g' = 104 + 103 = 207
'e' + 'o' = 101 + 111 = 212
'l' + 'o' = 108 + 111 = 219
'l' + 'd' = 108 + 100 = 208
'o' + 'b' = 111 + 98 = 209
'h' + 'y' = 104 + 121 = 225
'e' + 'e' = 101 + 101 = 202