convert bytes into hexadecimal in python - python

I am trying to multiply two data of bytes data type using python by trying to converting them into hexadecimal values. but it seems that the hex() function is not working. Can you please help me on that. Below is my code (x and y are our data of type bytes)
data=bytes.hex(x) * bytes.hex(y)
I am getting the error: TypeError:'str' object cannot be interpreted as an integer
by trying
data = hex(x) * hex(y)
the error become: TypeError:'bytes' object cannot be interpreted as an integer
Can anyone help please?

hex(my_var) returns a string. To do math you need to convert your variables to int:
x_int = int(x, base=16)
y_int = int(y, base=16)
decimal_value = x_int * y_int # integer
hex_value = hex(decimal_value) # string

data = hex(x) * hex(y)
This doesn't work because the hex() function expects an int as an argument and outputs a string.
In Python 3, you can do the following (interprets bytes as base 10)
data = hex(int(x)*int(y))

I see in the comments below your question that you have examples of your x and y values - you have some very large numbers to process if you interpret the bytes objects as arbitrary length integers. Not sure this is what you want, but this will do conversion of bytes to/from integer values.
>>> int_x = int.from_bytes(x, 'big') # From bytes to int.
>>> int_y = int.from_bytes(y, 'big')
>>> int_z = int_x * int_y # int_z as an integer.
>>>
>>> # Converting int_z to a bytes object:
>>>
>>> bytes_length = (int_z.bit_length() + 7) // 8
>>>
>>> z = int_z.to_bytes(bytes_length, 'big')
If you want them interpreted as little endian, replace 'big' with 'little'.
If your y value is already an int type, which it looks like in your comment, then don't convert it before multiplying:
>>> int_x = int.from_bytes(x, 'big')
>>> int_y = y
>>> int_z = int_x * int_y
>>> z = int_z.to_bytes(bytes_length, 'big')
The first parameter to int.to_bytes() is the length of the bytes object to create. There are other ways to calculate this value, but the way I included is the fastest method out of 3 that I timed.
If all you wanted to do was convert a bytes object to its hex string representation (z below is treated as a bytes object):
>>> hex_z = '0x' + ''.join(hex(b)[2:] for b in z)
Or to convert an int to a hex string:
>>> hex_z = hex(int_z)
hex() can handle very large integers.

Related

get bytes result from secrets.randbits() [duplicate]

I want to convert an 32-byte (although I might need other lengths) integer to a bytes object in python. Is there a clean and simple way to do this?
to_bytes(length, byteorder[, signed]) is all you need starting from 3.2. In this case, someidentifier.to_bytes(4,'big') should give you the bytes string you need.
I'm guessing you need a 32-bit integer, and big-endian to boot:
>>> from ctypes import c_uint32
>>> l = c_uint32(0x12345678)
>>> bytes(l)
b'xV4\x12'
There is c_uint8, c_uint16 and c_uint64 as well. For longer ints you need to make it manually, using divmod(x, 256).
>>> def bytify(v):
... v, r = divmod(v, 256)
... yield r
... if v == 0:
... raise StopIteration
... for r in bytify(v):
... yield r
...
>>> [x for x in bytify(0x12345678)]
[120, 86, 52, 18]
>>> bytes(bytify(0x12345678))
b'xV4\x12
>>> bytes(bytify(0x123456789098765432101234567890987654321))
b'!Ce\x87\t\x89gE#\x01!Ce\x87\t\x89gE#\x01'
You can use bytes("iterable") directly. Where every value in iterable will be specific byte in bytes(). Example for little endian encoding:
>>> var=0x12345678
>>> var_tuple=((var)&0xff, (var>>8)&0xff, (var>>16)&0xff, (var>>24)&0xff)
>>> bytes(var_tuple)
b'xV4\x12'
Suppose you have
var = 'і' # var is ukrainian і
We want to get binary from it.
Flow is this. value/which is string => bytes => int => binary
binary_var = '{:b}'.format(int.from_bytes(var.encode('utf-8'), byteorder='big'))
Now binary_var is '1101000110010110'. It type is string.
Now go back, you want get unicode value from binary:
int_var = int(binary_var, 2) # here we get int value, int_var = 53654
Now we need convert integer to bytes. Ukrainian 'і' is not gonna fit into 1 byte but in 2. We convert to actual bytes bytes_var = b'\xd1\x96'
bytes_var = int_var.to_bytes(2, byteorder='big')
Finally we decode our bytes.
ukr_i = bytes_var.decode('utf-8') # urk_i = 'і'

Converting hexstr to signed integer - Python

I have this hexstr 0xfffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877, in decimal terms it should give -580140491462537. However doing the below leads to bad answers. Can someone help?
In: test = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877'
In: int(test,16)
Out: 11579208923731619542357098500868790785326998466564056403945758342777263817739
First convert the string to bytes. You'll have to remove the leading "0x".
Then use int.from_bytes and specify that it's signed and big-endian.
In: int.from_bytes(bytes.fromhex(test[2:]), byteorder="big", signed=True)
Out: -580140491462537
I've adapted this answer
# hex string to signed integer
def htosi(val):
uintval = int(val, 16)
bits = 4 * len(val)
indicative_binary = 2 ** (bits)
indicative_binary_1 = 2 ** (bits-1)
if uintval >= indicative_binary_1:
uintval = int(0 - (indicative_binary - uintval))
return uintval
This does require a pure hex string:
test1 = 'fffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877'
print(htosi(test1))
-580140491462537

Python: XOR hex values in strings

Im new to python and I have (maybe) a dumb question.
I have to XOR two value. currently my values look like this:
v1 =
<class 'str'>
2dbdd2157b5a10ba61838a462fc7754f7cb712d6
v2 =
<class 'str'>
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
but the thing is, i need to XOR the actual HEX value instead of the ascii value of the given character in the string.
so for example:
the first byte in the first string is s1 = 2d, in the second string s2 = 5b
def sxor(s1,s2):
return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2))
this will not work, because it gives back the ASCII value of each character (then XOR them), which is obviously differs from the actual hex value.
Your mistake is converting the characters to their ASCII codepoints, not to integer values.
You can convert them using int() and format() instead:
return ''.join(format(int(a, 16) ^ int(b, 16), 'x') for a,b in zip(s1,s2))
int(string, 16) interprets the input string as a hexadecimal value. format(integer, 'x') outputs a hexadecimal string for the given integer.
You can do this without zip() by just taking the whole strings as one big integer number:
return '{1:0{0}x}'.format(len(s1), int(s1, 16) ^ int(s2, 16))
To make sure leading 0 characters are not lost, the above uses str.format() to format the resulting integer to the right length of zero-padded hexadecimal.
Parse the strings into int's then xor the ints:
def sxor(s1,s2):
i1 = int(s1, 16)
i2 = int(s2, 16)
# do you want the result as an int or as another string?
return hex(i1 ^ i2)
Works with python3:
_HAS_NUMPY = False
try:
import numpy
_HAS_NUMPY = True
except:
pass
def my_xor(s1, s2):
if _HAS_NUMPY:
b1 = numpy.fromstring(s1, dtype="uint8")
b2 = numpy.fromstring(s2, dtype="uint8")
return (b1 ^ b2).tostring()
result = bytearray(s1)
for i, b in enumerate(s2):
result[i] ^= b
return result

Convert bytes to int?

I'm currently working on an encryption/decryption program and I need to be able to convert bytes to an integer. I know that:
bytes([3]) = b'\x03'
Yet I cannot find out how to do the inverse. What am I doing terribly wrong?
Assuming you're on at least 3.2, there's a built in for this:
int.from_bytes( bytes, byteorder, *, signed=False )
...
The argument bytes must either be a bytes-like object or an iterable
producing bytes.
The byteorder argument determines the byte order used to represent the
integer. If byteorder is "big", the most significant byte is at the
beginning of the byte array. If byteorder is "little", the most
significant byte is at the end of the byte array. To request the
native byte order of the host system, use sys.byteorder as the byte
order value.
The signed argument indicates whether two’s complement is used to
represent the integer.
## Examples:
int.from_bytes(b'\x00\x01', "big") # 1
int.from_bytes(b'\x00\x01', "little") # 256
int.from_bytes(b'\x00\x10', byteorder='little') # 4096
int.from_bytes(b'\xfc\x00', byteorder='big', signed=True) #-1024
Lists of bytes are subscriptable (at least in Python 3.6). This way you can retrieve the decimal value of each byte individually.
>>> intlist = [64, 4, 26, 163, 255]
>>> bytelist = bytes(intlist) # b'#\x04\x1a\xa3\xff'
>>> for b in bytelist:
... print(b) # 64 4 26 163 255
>>> [b for b in bytelist] # [64, 4, 26, 163, 255]
>>> bytelist[2] # 26
list() can be used to convert bytes to int (works in Python 3.7):
list(b'\x03\x04\x05')
[3, 4, 5]
int.from_bytes( bytes, byteorder, *, signed=False )
doesn't work with me
I used function from this website, it works well
https://coderwall.com/p/x6xtxq/convert-bytes-to-int-or-int-to-bytes-in-python
def bytes_to_int(bytes):
result = 0
for b in bytes:
result = result * 256 + int(b)
return result
def int_to_bytes(value, length):
result = []
for i in range(0, length):
result.append(value >> (i * 8) & 0xff)
result.reverse()
return result
In case of working with buffered data I found this useful:
int.from_bytes([buf[0],buf[1],buf[2],buf[3]], "big")
Assuming that all elements in buf are 8-bit long.
An old question that I stumbled upon while looking for an existing solution. Rolled my own and thought I'd share because it allows you to create a 32-bit integer from a list of bytes, specifying an offset.
def bytes_to_int(bList, offset):
r = 0
for i in range(4):
d = 32 - ((i + 1) * 8)
r += bList[offset + i] << d
return r
#convert bytes to int
def bytes_to_int(value):
return int.from_bytes(bytearray(value), 'little')
bytes_to_int(b'\xa231')

Python - Decimal to Hex, Reverse byte order, Hex to Decimal

I've been reading up a lot on stuct.pack and hex and the like.
I am trying to convert a decimal to hexidecimal with 2-bytes. Reverse the hex bit order, then convert it back into decimal.
I'm trying to follow these steps...in python
Convert the decimal value **36895** to the equivalent 2-byte hexadecimal value:
**0x901F**
Reverse the order of the 2 hexadecimal bytes:
**0x1F90**
Convert the resulting 2-byte hexadecimal value to its decimal equivalent:
**8080**
Bit shifting to swap upper/lower eight bits:
>>> x = 36895
>>> ((x << 8) | (x >> 8)) & 0xFFFF
8080
Packing and unpacking unsigned short(H) with opposite endianness(<>):
>>> struct.unpack('<H',struct.pack('>H',x))[0]
8080
Convert 2-byte little-endian to big-endian...
>>> int.from_bytes(x.to_bytes(2,'little'),'big')
8080
To convert from decimal to hex, use:
dec = 255
print hex(dec)[2:-1]
That will output the hex value for 255.
To convert back to decimal, use
hex = 1F90
print int(hex, 16)
That would output the decimal value for 1F90.
You should be able to reverse the bytes using:
hex = "901F"
hexbyte1 = hex[0] + hex[1]
hexbyte2 = hex[2] + hex[3]
newhex = hexbyte2 + hexbyte1
print newhex
and this would output 1F90. Hope this helps!
Keep in mind that 'hex'(base 16 0-9 and a-f) and 'decimal'(0-9) are just constructs for humans to represent numbers. It's all bits to the machine.
The python hex(int) function produces a hex 'string' . If you want to convert it back to decimal:
>>> x = 36895
>>> s = hex(x)
>>> s
'0x901f'
>>> int(s, 16) # interpret s as a base-16 number
Print formatting also works with strings.
# Get the hex digits, without the leading '0x'
hex_str = '%04X' % (36895)
# Reverse the bytes using string slices.
# hex_str[2:4] is, oddly, characters 2 to 3.
# hex_str[0:2] is characters 0 to 1.
str_to_convert = hex_str[2:4] + hex_str[0:2]
# Read back the number in base 16 (hex)
reversed = int(str_to_convert, 16)
print(reversed) # 8080!
My approach
import binascii
n = 36895
reversed_hex = format(n, 'x').decode('hex')[::-1]
h = binascii.hexlify(reversed_hex)
print int(h, 16)
or one line
print int(hex(36895)[2:].decode('hex')[::-1].encode('hex'), 16)
print int(format(36895, 'x').decode('hex')[::-1].encode('hex'), 16)
print int(binascii.hexlify(format(36895, 'x').decode('hex')[::-1]), 16)
or with bytearray
import binascii
n = 36895
b = bytearray.fromhex(format(n, 'x'))
b.reverse()
print int(binascii.hexlify(b), 16)

Categories

Resources