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.
Related
E.g. in a given input the fourth digit must be one greater than the fifth digit
input = "5000-0000-0000"
if input[3] != input[5] + 1
return false
If you think about what input[3] and input[5] are, you will pretty quickly realize they are characters and not numbers that can be added or compared with mathematical operations (think about what would happen if you wrote input = "Andrew Francis").
You can see this by using print(type(input[3])).
Fortunately, if you have a string that contains only characters that make up a valid number, you can convert it to (for instance) an integer using the int() function. So, try print(type(int(input[3]))) and see what you get.
First of all, I have only recently started to learn Python on codeacademy.com and this is probably a very basic question, so thank you for the help and please forgive my lack of knowledge.
The function below takes positive integers as input and returns the sum of all that numbers' digits. What I don't understand, is why I have to change the type of the input into str first, and then back into integer, in order to add the numbers' digits to each other. Could someone help me out with an explanation please? The code works fine for the exercise, but I feel I am missing the big picture here.
def digit_sum(n):
num = 0
for i in str(n):
num += int(i)
return num
Integers are not sequences of digits. They are just (whole) numbers, so they can't be iterated over.
By turning the integer into a string, you created a sequence of digits (characters), and a string can be iterated over. It is no longer a number, it is now text.
See it as a representation; you could also have turned the same number into hexadecimal text, or octal text, or binary text. It would still be the same numerical value, just written down differently in text.
Iteration over a string works, and gives you single characters, which for a number means that each character is also a digit. The code takes that character and turns it back into a number with int(i).
You don't have to use that trick. You could also use maths:
def digit_sum(n):
total = 0
while n:
n, digit = divmod(n, 10)
num += digit
return num
This uses a while loop, and repeatedly divides the input number by ten (keeping the remainder) until 0 is reached. The remainders are summed, giving you the digit sum. So 1234 is turned into 123 and 4, then 12 and 3, etc.
Let's say the number 12345
So I would need 1,2,3,4,5 from the given number and then sum it up.
So how to get individuals number. One mathematical way was how #Martijn Pieters showed.
Another is to convert it into a string , and make it iterable.
This is one of the many ways to do it.
>>> sum(map(int, list(str(12345))))
15
The list() function break a string into individual letters. SO I needed a string. Once I have all numbers as individual letters, I can convert them into integers and add them up .
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.
I am doing an assignment to decipher a one-time-pad code (7 sentences, repeated keys for each character position among all 7 sentences). I'm solving it by guess work and I need to XOR the binary value of my guess letter with the binary value of the cypher character in order to get a key.
However, I cannot XOR the binary values returned by Python as they are in string format. I cannot convert them to integers since I need the '0b' part, but I also cannot XOR it because it's a string.
Any suggestions as to how to work around this?
Integers in Python support binary bitwise operations; the binary bitwise operators take integer operands and produce new integers with the bits altered, just like they would in C code.
Convert your string (presumably you have something like 0b1001101) to integer, use the ^ XOR operator on that. If you need string output at the end, you can always use bin() again on the integer:
>>> bin(102)
'0b1100110'
>>> 102 ^ 255
153
>>> bin(102 ^ 255)
'0b10011001'
If you have ASCII bytes (characters in Python 2 strings are bytes), use ord() to get an integer representation, chr() to go back to a byte (character) again.
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.