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.
Related
I can't quite find a solution for this.
Basically what I've done so far is created a string which represents the binary version of x amount of characters padded to show all 8 bits.
E.g. if x = 2 then I have 0101100110010001 so 8 digits in total. Now I have 2 strings of the same length which I want to XOR together, but python keeps thinking it's a string instead of binary. If I use bin() then it throws a wobbly thinking it's a string which it is. So if I cast to an int it then removes the leading 0's.
So I've already got the binary representation of what I'm after, I just need to let python know it's binary, any suggestions?
The current function I'm using to create my binary string is here
for i in origAsci:
origBin = origBin + '{0:08b}'.format(i)
Thanks in advance!
Use Python's int() function to convert the string to an integer. Use 2 for the base parameter since binary uses base 2:
binary_str = '10010110' # Binary string
num = int(binary_str, 2)
# Output: 150
Next, use the bin() function to convert the integer to binary:
binary_num = bin(num)
# Output: 0b10010110
x = 64
var_in_bin_format = bin(64)
print(var_in_bin_format)
#Output
#0b1000000
#Desired Output -- > should always be in 8 bit format
#0b01000000
def call_another_api(var_in_bin_format):
pass
In Python, I need to call an API that expects its parameter to be always in 8 bit format regardless of the value of the decimal number?
I am not that good in bit manipulation so I am thinking if there is something I can do here?
How can I do this? I cannot use the format() function as it will convert the value into a string representation and the API that I am calling will alert me that it is not in the correct format.
Even though you say that you can't use format() because it returns a string, I'm going to post this because that's also what bin() does. bin(x) is equivalent to format(x, '#b'). I'd guess that you haven't added the '#', which means you won't have '0b' leading the value.
The Python 3 documentation for bin() actually gives a pretty strong hint about how you might do this, using format instead.
If you know that the value passed will not be negative, you can use the format string '#010b':
format(x, '#010b')
Breaking this down:
'b' means that the number will be a string binary representation.
'10' means that the entire string will be 10 characters long, two for '0b' and 8 for the value.
'0' makes it pad with '0' instead of ' '.
'#' will add the '0b' prefix, as done by bin().
Note that this assumes that the number is an integer in the range [0, 255]. Integers outside this range will generate valid representations, but will not match the format expected, and may have a leading '-'. Objects of type float can not be converted with the 'b' format code. I assume that these are not problems, given what your intended output is, but it might be a good idea to add an explicit check to throw a ValueError if the value is less than 0 or greater than 255.
If you're in Python 3.6+, you could also use f-strings:
f'{x:#010b}'
Is is not possible to convert all decimal numbers to 8 bit. You can only convert numbers from 0 to 255 in 8 bits.
I'm trying to write an implementation of SHA-256 in python 3. My version is supposed to take in a hexadecimal encoding and output the corresponding hash value. I've used https://en.wikipedia.org/wiki/SHA-2#Pseudocode as guide.
My function works well for most inputs but sometimes it gives an output that is only 63bits (instead of 64). My function uses 32bit binary strings.
I think I have found the problem, in the last step of the algorithm the binary addition
h4 := h4 + e (or another h-vector and corresponding letter)
yields a binary number that is too small. The last thing I do is to use hex() and I should get a string of 8 characters. In this example I only get 7.
out4 = hex(int(h4,2))[2:]
One problematic input is e5e5e5
It gives
"10110101111110101011010101101100" for h4 and "01010001000011100101001001111111" for e
so the addition gives "00000111000010010000011111101011"
and out4 = 70907eb.
What should I do in these cases?
I should get a string of 8 characters
Why do you think so? hex doesn't allow to specify the length of the output to begin with, so, for example, if the correct output is 8 bytes of zeros, hex will return 0x0 - the shortest representation possible.
I'm guessing the correct output should begin with zero, but hex is cutting it off. Use format strings to specify the length of output:
In [1]: f'{0:08x}'
Out[1]: '00000000' # lowercase hexadecimal (x) digits that must fit into at least 8 characters, prefixed with zero (08) as needed
I dont know why Hex function returns a string like '0x41' instead 0x41
I need to convert an ASCII value into a hex. But i want in 0x INT format, not into a '0x' string.
ascii = 360
hexstring = hex(ascii)
hexstring += 0x41 # i cant do this because hexstring is a string not a int hex
How i can get a int hex??
thanks
There is no int hex object. There is only an alternative syntax to create integers:
>>> 0x41
65
You could have used 0o1010 too, to get the same value. Or use 0b1000001 to specify it in binary; they are all the exact same numeric value to Python; they are all just different forms to specify an integer value in your code.
Simply keep ascii as an integer and sum your hex notation values with that:
>>> ascii = 360
>>> ascii += 0x41
>>> ascii
425
hex() produces a string that can be interpreted by a Python program in the same manner, and is usually used when debugging code or quick presentation output (but you should use format(number, 'x') if you want to produce end-user output without the 0x prefix). It is not needed to work with integers.
I followed the great example at Python: Nicest way to pad zeroes to string (4)
but now I need to turn that padded string to a padded integer.
I tried:
list_padded=['0001101', '1100101', '0011011', '0011011', '1101111',
'0000001', '1110111', 1101111', '0111001', '0011011',
'0011001'] # My padded sting list.
int_list=[int(x) for x in list_padded] # convert the string to an INT
But what I get is a list of integers sans the padding.
Appreciate any direction or suggestions.
Many thanks,
Jack
Edit: After learning the revelation that integers don't get padded, I'm thinking a little differently, however it would probably be a good idea to explain more:
I'm working through a basic encryption exercise in a book. It has given me a list of pseduocode to work through - get cipher string 1-127 and a message, convert both to binary, strip off the 0b, and pad with zeroes. However it wants me to do the rest WITHOUT XOR! I've gotten that far one line at a time, but now comes this (where the problem begins):
Perform manual XOR operation & append binary 7-bit result to encrypted string
Convert each binary bit of message character and key to an integer
Perform XOR operation on these two bits
Convert literal True and False to binary bit & append to output
I've love to use the XOR operation but I'm afraid doing so I'm not going to learn what I need to.
-J
Applying idea of padding to integers is meaningless. If you want to print/represent them you need strings, integers just don't have padding.
Integers don't have a concept of padding, but if you want then you can store both the value and the original length instead of just the value:
int_list = [(int(x), len(x)) for x in list_padded]
Then if you want to reconstruct the original data you have enough information to do so. You may even want to make a custom class to store both these fields instead of using a tuple.
Leading zeros is just for data representation:
"{0:b}".format(4).zfill(8)
You can change XOR with other bit-wise operations:
def xor(x, y):
return (~x & y) | (~y & x)
def bool_xor(x, y):
return ((not x) and y) or ((not y) and x)
Actually, you can express all bitwise operations with just one logical operation:
http://en.wikipedia.org/wiki/Functional_completeness
Since the INT type is a number it will be stored without leading zeros. Why would you want to store 675 as 00675? That's meaningless in the realm of integers. I would suggest storing the integers as integers and then only apply the padding when you access them and print them out (or whatever you are doing with them)