Trouble getting the correct output of code? - python

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.)

Related

Python - Pseudocode to decrypt a XOR encrypted string

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.

Add a number to each element/integer in an array

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.

Python encryption program (ECC)

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])

Xor Encryption/Decryption Python 2.7.5 [duplicate]

This question already has answers here:
XOR Python Text Encryption/Decryption
(4 answers)
Closed 8 years ago.
I know there is a built in xor operator that can be imported in Python. I'm trying to execute the xor encryption/decryption. So far I have:
def xor_attmpt():
message = raw_input("Enter message to be ciphered: ")
cipher = []
for i in message:
cipher.append(bin(ord(i))[2::])#add the conversion of the letters/characters
#in your message from ascii to binary withoout the 0b in the front to your ciphered message list
cipher = "".join(cipher)
privvyKey = raw_input("Enter the private key: ")
keydecrypt = []
for j in privvyKey:
keydecrypt.append(bin(ord(j))[2::]) #same
keydecrypt = "".join(keydecrypt )#same
print "key is '{0}'" .format(keydecrypt) #substitute values in string
print "encrypted text is '{0}'" .format(cipher)
from operator import xor
for letter in message:
print xor(bool(cipher), bool(keydecrypt))
This:
> for letter in message:
print xor(bool(cipher), bool(keydecrypt))
is where my python starts to go wrong.
The ouput looks like this
Enter message to be ciphered: hello
Enter the private key: \#154>
key is '10111001000000110001110101110100111110'
encrypted text is '11010001100101110110011011001101111'
False
False
False
False
False
What I'm messing up on is trying to get these two binary(key and encrypted) to be compared and give true(1) or false(being 0). The xor should then give me a resulting 1 and 0 binary list from comparing the two. Any input?
The bool() constructor converts any value into either True or False. Since you are passing it a non-empty string in each case bool(cipher) and bool(keydecrypt) each just convert to True and xor(True,True) is `False.
Forget about converting to a string of 0 and 1, all you actually need to do is xor the character codes you get from calling ord() and then convert back to a character with chr(). also, you don't need to import a function, Python has a perfectly functional xor operator ^.
Something like this ought to work:
import itertools
print(''.join(chr(ord(k)^ord(c)) for c,k in zip(cipher,itertools.cycle(keydecrypt))))
You made some mistakes:
cipher and keydecrypt are not binary, they are strings containing 0 and 1 characters.
There is no need to import xor function, you already have the xor operator ^
Converting a string to boolean in python will get you False if string == '' and True in every other case, which is not what you want.
I didn't understand what the last for is supposed to do.
Here is an example about how you could improve you code:
import itertools
import binascii
encrypted = ''
for m, k in itertools.izip(message, itertools.cycle(key)):
encrypted += chr(ord(m) ^ ord(k))
print binascii.hexlify(encrypted)
This would work also if key is smaller than message.

Need Assistance in Calculating Checksum

I am working on an interface in Python to a home automation system (ElkM1). I have sample code in C# below which apparently correctly calculates the checksum needed when sending messages to this system. I put together the python code below but it doesn't appear to be returning the correct value.
According to the documentation the checksum of the message needs to be the sum of the ASCII values of the message in mod256 then taken as 2s complement. From their manual: "This is the hexadecimal two‟s complement of the modulo-256 sum of the ASCII values of all characters in the message excluding the checksum itself and the CR-LF terminator at the end of the message. Permissible characters are ASCII 0-9 and upper case A-F. When all the characters are added to the Checksum, the value should equal 0."
The vendor has a tool which will calculate the correct checksum. As test data I have been using '00300005000' which should return a checksum of 74
My code returns 18
Thanks in advance.
My Code (Python)
def calc_checksum (string):
'''
Calculates checksum for sending commands to the ELKM1.
Sums the ASCII character values mod256 and takes
the Twos complement
'''
sum= 0
for i in range(len(string)) :
sum = sum + ord(string[i])
temp = sum % 256 #mod256
rem = temp ^ 256 #inverse
cc1 = hex(rem)
cc = cc1.upper()
p=len(cc)
return cc[p-2:p]
Their Code C#:
private string checksum(string s)
{
int sum = 0;
foreach (char c in s)
sum += (int)c;
sum = -(sum % 256);
return ((byte)sum).ToString("X2");
}
FWIW, here's a literal translation of the C# code into Python:
def calc_checksum(s):
sum = 0
for c in s:
sum += ord(c)
sum = -(sum % 256)
return '%2X' % (sum & 0xFF)
print calc_checksum('00300005000')
It outputs is E8 for the message shown which is different from both your and the C# code. Given the description in the manual and doing the calculations by hand, I don't see how their answer could be 74. How do you know that's the correct answer?
After seeing Mark Ransom's comment that the C# code does indeed return E8, I spent some time debugging your Python code and found out why it doesn't produce the same result. One problem is that it doesn't calculate the two's complement correctly on the line with the comment #inverse in your code. There's at least a couple of ways to do that correctly.
A second problem is way the hex() function handles negative numbers is not what you'd might expect. With the -24 two's complement in this case it produces -0x18, not 0xffe8 or something similar. This means that just taking the last two characters of the uppercased result would be incorrect. An really easy way to do that is just convert the lower byte of the value to uppercase hexadecimal using the % string interpolation operator. Here's a working version of your function:
def calc_checksum(string):
'''
Calculates checksum for sending commands to the ELKM1.
Sums the ASCII character values mod256 and takes
the Twos complement.
'''
sum = 0
for i in range(len(string)):
sum = sum + ord(string[i])
temp = sum % 256 # mod256
# rem = (temp ^ 0xFF) + 1 # two's complement, hard way (one's complement + 1)
rem = -temp # two's complement, easier way
return '%2X' % (rem & 0xFF)
A more Pythonic (and faster) implementation would be a one-liner like this which makes use of the built-in sum() function:
def calc_checksum(s):
"""
Calculates checksum for sending commands to the ELKM1.
Sums the ASCII character values mod256 and returns
the lower byte of the two's complement of that value.
"""
return '%2X' % (-(sum(ord(c) for c in s) % 256) & 0xFF)

Categories