I am creating a very simple encryption algorithm where I covert each letter of a word into ascii, placing the ascii values into an array and then adding a number onto each value. To then convert the ascii back to letters, which will then output the new encrypted word. Known as the ceaser cipher.
But I cannot figure out how to add the key number to each element of the array.
As others will mention, when posing a question like this, please post a code attempt first. Having clear input/output and any associated stack trace errors helps people answer your question better.
That being said, I've written a simple ceaser cipher encryption method that shifts to the right based on a given key. This works by converting the characters of a string to their numerical ascii representations using the built in method ord(). We then add the shift value to this representation to right shift the values over by a given amount. Then covert back to characters using chr() We take into account some wrapping back to the beginning of the alphabet if the shifted_value exceeds that of 'z'.
def ceaser_cipher_encryption(string, shift):
alpha_limit = 26
encrypted_msg = []
for index, character in enumerate(string.lower()):
isUpperCharacter = string[index].isupper()
shifted_value = ord(character) + shift
if shifted_value > ord('z'):
encrypted_msg.append(chr(shifted_value - alpha_limit))
else:
encrypted_msg.append(chr(shifted_value))
if isUpperCharacter:
encrypted_msg[index] = encrypted_msg[index].upper()
return ''.join(encrypted_msg)
Sample Output:
>>> ceaser_cipher_encryption("HelloWorld", 5)
MjqqtBtwqi
Try having a look online for solutions:
Caesar Cipher Function in Python
https://inventwithpython.com/chapter14.html
These links will provide you with clear answers to your questions.
Related
I'm trying to improve my coding skills on entwicklerheld.de
and right now I'm trying to solve the transposition cipher challenge:
We consider a cipher in which the plaintext is written downward and diagonally in successive columns. The number of rows or rails is given. When reaching the lowest rail, we traverse diagonally upwards, and after reaching the top rail, there is a change of direction again. Thus, the alphabets [sic] of the message are written in a zigzag pattern. After each alphabet is written, the individual lines are combined to obtain the cipher text.
Given is the plain text "coding" and the number of rails 2. The plain text is now arranged in a zigzag pattern as described above. The encoded text is obtained by combining the lines one after the other.
Thus, the encrypt() function should return the cipher "cdnoig".
The same procedure is used for entire sentences or texts as for individual words. The only thing to note here is that spaces also count as a single character.
Given is the plain text "rank the code" and the number of rails 2.
Your function should return the cipher "rn h oeaktecd".
This should work with other examples with 2 rails as well.
The encryption is very easy with a multi dimensional array.
My question
I'm stuck at the decryption part.
My idea is to build an array with 0 and 1 (to show were a character has to be). Then fill every array (line 1... line 2 ... line 3) with the characters in the order of the cipher text.
Then I iterate a third time over the array to read the word in zig-zag.
I don't know, but it feels very strange to iterate 3 times over the array. Maybe there is a zig-zag algorithm or so?
You could first define a generator that gives the mapping for each index to the index where the character has to be taken from during encryption. But this generator would not need to get the plain text input, just the length of it. As this generator just produces the indices, it can be used to decrypt as well.
It was not clear to me whether the question is only about the case where the number of rails is 2. With a bit of extra logic, this can be made for any greater number of rails also.
Here is how that could look:
# This generator can be used for encryption and decryption:
def permutation(size, numrails):
period = numrails * 2 - 2
yield from range(0, size, period) # top rail
# Following yield-from statement only needed when number of rails > 2
yield from (
index
for rail in range(1, numrails - 1)
for pair in zip(range(rail, size, period),
range(rail + period - rail*2, size + period, period))
for index in pair
if index < size
)
yield from range(numrails - 1, size, period) # bottom rail
def encrypt(plain, numrails):
n = len(plain)
return "".join([plain[i] for i in permutation(n, numrails)])
def decrypt(encrypted, numrails):
n = len(encrypted)
plain = [None] * n
for source, target in enumerate(permutation(n, numrails)):
plain[target] = encrypted[source]
return "".join(plain)
The original encryption is as follows (which i've already done):
For every letter in the key and every letter in the plaintext ( they are the same length) you compute the ascii values, find the XOR result, convert that to decimal, add 32 to that value and then convert back to char. The char would be the ciphertext. .
key = this is a cool key
plaintext = Wonderland is cool
ciphertext= C''7e;?a/dc&<lc$*5
def decryption(ciphertext,key):
plaintext = ""
for k in range(len(ciphertext)):
i = ciphertext[k]
j = key[k]
val = xor_calc(chr(ord(i)-32), chr(ord(j)-32))
val = chr(ord(xor)+ 32)
plaintext += val
after decryption im getting:
onderland is cool
obviously should match the original plaintext, additionally with other ciphers and keys im missing letters. My encryption works fine though, as my answers match what the results should be. Any help would be appreciated!
Forgot to mention i have a function xor_calc that takes the cipher and key letters, converts to ascii and computes the XOR results and returns back to char
Simplifying you calculation of xor worked for me:
xor = chr((ord(i)-32) ^ (ord(j)-32) + 32)
In fact, if I run decryption(plaintext,key), I get your ciphertext; if run decryption(ciphertext,key), I get your plaintext. (This makes sense, since xor is reversible.)
I'm trying to solve this challenge and having some trouble. First, I'm not super familiar with XOR. I understand that XOR is symmetric so all I need to do to decrypt this string is encrypt it again with the same key, which I have.
I don't want an answer handed to me, so if possible can someone assist with kickstarting my brain with some pseudocode on how you would create a Python script to take a users input, and decrypt their XOR encrypted string?
Let me explain it this way.
XOR table
=========
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
So, imagine a binary number
10110011
And, you have a key
11001100
If you XOR them you get:
01111111
With me? Now, XOR the encrypted number with the key, and you return back to original.
10110011
Here is some pseudo-code as well for this. It is a heavy to demonstrate the work.
Get the input-string from user
Get the encrypt-key from user #Assume it is also a string;
Loop through the input-string character by character
Convert character to its binary representation as a string
Concatenate that to input-string-converted-to-binary string
Loop through the encrypt-key character by character
Convert character to its binary representation as a string
Concatenate that to encrypt-key-converted-to-binary string
Get the length of the encrypt-key-converted-to-binary string
Calculate totalloops by dividing that into the length of the input-string-converted-to-binary string
Loop for totalloops
Loop for each character in the subsection of the input-string-converted-to-binary string
Calculate XOR of the digit
Concatenate into encrypted-value string
You now have the binary string. You can reverse the process of converting the binary string into characters. But, you may get unprintable characters, which is why doing it the long way gives you more to inspect.
user_number = input("Enter your number")
if( user_number. isdigit()):
print("User input is Number ")
else:
print("User input is string ")
because its two inputs cannot be unambiguously reconstructed
from its single output.
I've been working on some homework I've been given and I've ran into a couple problems. I'm hoping someone can shed some light on them and perhaps give me some examples to help aide me.
My first question deals with binary operators in python.
Problem #13: Python supports 18 different binary operators. Experiment with each of these, using arguments that are both integer, both floating point, and both string. Not all operators work with each argument type. Fill in the following table. For each operator, provide either a short description and indicate the type of the result or the words “not legal”.
Operator Integer Floating point String
+
-
*
**
/
%
<<
>>
&
|
^
<
>
<=
>=
==
!=
<>
In this example we're supposed to explain how to operator works as an integer, float point and a string. What confuses me is the float and string aspect, using the addition portion as an example:
Would the integer aspect be something like x=3 y=4 x+y=answer (to show as an integer)? If so how would I go about showing examples of the float and string portion.
My second question deals with string splitting
Problem #20: Each row in the following table consists of a starting word and an ending word. Assign the starting word to the name w. Then using only indexing and slicing commands, convert the starting word into the ending word.
Starting word Ending word Command
w=’kyoto’ ‘tokyo’ w[3:]+w[:3]
w=’bread’ ‘bead’ w[0]+w[2:]
w=’kartasura’ ‘surakarta’ w[5:]+w[:5]
w=’listen’ ‘silent’
As you can see I've completed the first three which seemed relatively simple, I had to rearrange the words. The final one confuses me because I am not longer flipping the back with the front or vise versa. Instead I am rotating sections, now I am rotating lis to sil and ten to ent and I'm not exactly sure how to rotate letters.
Any help would be greatly appreciated, TY.
What confuses me is the float and string aspect, using the addition portion as an example?
3 + 4
3.5 + 4.25
'hello' + ' world'
The final one confuses me because I am not longer flipping the back with the front or vise versa.
w[2::-1] + w[4:6] + w[3]
I'm trying to code an encryption program that will encode a user's Inputed - if that's a word - string. The encryption method is just a basic use of an elliptic curve encryption and I am currently working on the encryption part of the program at the moment before I work on the mathematical, inverse modules etc. Etc. Required for public and private key calculations. Currently I am using the key pub = 5 and a max value (derived from the product of 2 random primes) of 91. This is all the information needed and the word I am testing the encryption on is 'happy'.
So far here is the code.
word = 'happy'
pub = 5
m = 91
for i in range(pub):
if i == 0:
word = word
else:
word = output
for x in word:
a = [(((ord(z)*ord(z))+1)/m) for z in word]
b = [chr(i) for i in a]
c = [str(i) for i in b]
d = ''.join([str(i) for i in c])
output = d
What I am trying to do is encrypt each letter by multiplying the ASCII value it belongs too by itself and then use the chr() function to rejoin the string after a process of adding 1 then dividing by m , thus creating a new word. Then, using that new string, set it as the value of word for the next cycle in the loop, so the process continues until it has finished pub amount of times and encrypted the word. I'm having a lot of difficulties with this and I don't know where to start with explaining the issues. I'm relatively new to Python and any suggestions and/or advice on completing this fast would be very much appreciated. Thank you in advance.
First, check that your math is right. Your formula (z**2 + 1)/m grows quadratically. My understanding of crypto is quite limited, but it doesn't look right to me. It should be some kind of one-to-one mapping from input to output. But it maps several neighboring characters to the same output. Also, the results grow with every round.
You can only convert the integers back to ascii characters for a range up to 256. That's what your error message says. It's proably thrown in the second iteration of your outer for loop.
You probably need to get the value range down to 256 again.
I suppose you miss a crucial part off the algorithm you are trying to implement, maybe some modulo operation.
Also some minor python hints:
You can use the built in power operator **, so you don't have to evaluate ord() twice.
((ord(z) ** 2) + 1) / m
You can do the conversion back to the string in one step like this:
output = ''.join([str(chr(i)) for i in a])