I have the following code:
msg = b'0,[\x00\x01\x86\xec\x96N'
print(struct.unpack("<"+"I",msg))
however everytime i try to do this it says
struct.error: unpack requires a buffer of 4 bytes
What i tried to do is the following
times = int(len(msg)/4)
struct.unpack("<"+"I" * times,msg)
but it doesnt always work, i think on uneven numbers, how can i get the correct size so i dont encounter these issues?
struct.unpack requires that the length of the buffer being consumed is exactly the size of the format. [1]
Use struct.unpack_from instead, which requires that the length of the buffer being consumed is at least the size of the format. [2]
>>> msg = b'0,[\x00\x01\x86\xec\x96N'
>>> import struct
>>> print(struct.unpack("<"+"I", msg))
Traceback (most recent call last):
File "<input>", line 1, in <module>
struct.error: unpack requires a buffer of 4 bytes
>>> print(struct.unpack_from("<"+"I", msg))
(5975088,)
Additional bytes will be ignored by unpack_from
[1] https://docs.python.org/3/library/struct.html#struct.unpack
[2] https://docs.python.org/3/library/struct.html#struct.unpack_from
Related
I am trying to send data over a TCP connection from rust to python, however while receiving the data in python I am getting the following error when trying to convert it from bytes to f64.
Traceback (most recent call last):
File "server.py", line 36, in <module>
[x] = struct.unpack('f', data)
struct.error: unpack requires a buffer of 4 bytes
I am using the follwoing method to convert the data from bytes to f64,
[x] = struct.unpack('f', data)
print(x)
my data looks like this, which I am sending over a tcp
x: 0.011399809271097183 (f64 from rust)
and getting something like
b'?t=*\x00\x00\x00\x00?s\xbd\xc6\x80\x00\x00\x00?q\xd5s\x00\x00\x00\x00?|\xae\x85\x80\x00\x00\x00?e\xb5\xc3\x00\x00\x00\x00?yp;\x80\x00\x00\x00?p\x7f\x98\x00\x00\x00\x00?hG|\x00\x00\x00\x00?o\x8d&\x00\x00\x00\x00?cv[\x00\x00\x00\x00?s\xdf\x97\x80\x00\x00\x00?{\x0e\xde\x80\x00\x00\x00?n\xec\xbf\x00\x00\x00\x00?n\xd8E\x00\x00\x00\x00?y+\xdd\x80\x00\x00\x00?r\xd90\x80\x00\x00\x00?r\xc2\x89\x00\x00\x00\x00?q\xc2i\x00\x00\x00\x00?kq"\x00\x00\x00\x00?t5\xec\x80\x00\x00\x00?|\xaak\x80\x00\x00\x00?z\x10\x9d\x00\x00\x00\x00?o\xeb\xde\x00\x00\x00\x01?m6\xfc\x00\x00\x00\x00'
It appears 24 8-byte floats (double type in C) were sent in big-endian format. At least the data appears as something reasonable, although none of them match the single value listed in the question:
>>> data = b'?t=*\x00\x00\x00\x00?s\xbd\xc6\x80\x00\x00\x00?q\xd5s\x00\x00\x00\x00?|\xae\x85\x80\x00\x00\x00?e\xb5\xc3\x00\x00\x00\x00?yp;\x80\x00\x00\x00?p\x7f\x98\x00\x00\x00\x00?hG|\x00\x00\x00\x00?o\x8d&\x00\x00\x00\x00?cv[\x00\x00\x00\x00?s\xdf\x97\x80\x00\x00\x00?{\x0e\xde\x80\x00\x00\x00?n\xec\xbf\x00\x00\x00\x00?n\xd8E\x00\x00\x00\x00?y+\xdd\x80\x00\x00\x00?r\xd90\x80\x00\x00\x00?r\xc2\x89\x00\x00\x00\x00?q\xc2i\x00\x00\x00\x00?kq"\x00\x00\x00\x00?t5\xec\x80\x00\x00\x00?|\xaak\x80\x00\x00\x00?z\x10\x9d\x00\x00\x00\x00?o\xeb\xde\x00\x00\x00\x01?m6\xfc\x00\x00\x00\x00'
>>> s
b'?t=*\x00\x00\x00\x00?s\xbd\xc6\x80\x00\x00\x00?q\xd5s\x00\x00\x00\x00?|\xae\x85\x80\x00\x00\x00?e\xb5\xc3\x00\x00\x00\x00?yp;\x80\x00\x00\x00?p\x7f\x98\x00\x00\x00\x00?hG|\x00\x00\x00\x00?o\x8d&\x00\x00\x00\x00?cv[\x00\x00\x00\x00?s\xdf\x97\x80\x00\x00\x00?{\x0e\xde\x80\x00\x00\x00?n\xec\xbf\x00\x00\x00\x00?n\xd8E\x00\x00\x00\x00?y+\xdd\x80\x00\x00\x00?r\xd90\x80\x00\x00\x00?r\xc2\x89\x00\x00\x00\x00?q\xc2i\x00\x00\x00\x00?kq"\x00\x00\x00\x00?t5\xec\x80\x00\x00\x00?|\xaak\x80\x00\x00\x00?z\x10\x9d\x00\x00\x00\x00?o\xeb\xde\x00\x00\x00\x01?m6\xfc\x00\x00\x00\x00'
>>> len(data)
192
>>> len(s)/8
24.0
>>> import struct
>>> struct.unpack('>24d',s)
(0.004941143095493317, 0.004819655790925026, 0.004353951662778854, 0.007002374157309532, 0.0026501473039388657, 0.0062105488032102585, 0.00402793288230896, 0.0029637739062309265, 0.0038514845073223114, 0.0023757722228765488, 0.004851905629038811, 0.006605977192521095, 0.0037749987095594406, 0.003765234723687172, 0.006145348772406578, 0.004601659253239632, 0.004580054432153702, 0.004335794597864151, 0.003349844366312027, 0.0049342382699251175, 0.006998462602496147, 0.0063634999096393585, 0.003896649926900864, 0.003566257655620575)
I'm using the standard Python3 lib binascii, and specifically the crc_hqx() function
binascii.crc_hqx(data, value)
Compute a 16-bit CRC value of data, starting with value as the initial CRC, and return the result. This uses the CRC-CCITT polynomial x16 + x12 + x5 + 1, often represented as 0x1021. This CRC is used in the binhex4 format.
I'm able to convert to CRC with this code:
import binascii
t = 'abcd'
z = binascii.crc_hqx(t.encode('ascii'), 0)
print(t,z)
which, as expected, prints the line
abcd 43062
But how do I convert back to ASCII?
I've tried variations with the a2b_hqx() function
binascii.a2b_hqx(string)
Convert binhex4 formatted ASCII data to binary, without doing RLE-decompression. The string should contain a complete number of binary bytes, or (in case of the last portion of the binhex4 data) have the remaining bits zero.
The simplest version would be:
y = binascii.a2b_hqx(str(z))
But I've also tried variations with bytearray() and str.encode(), etc.
For this code:
import binascii
t = 'abcd'
z = binascii.crc_hqx(t.encode('ascii'), 0)
print(t,z)
y = binascii.a2b_hqx(str(z))
the Traceback:
abcd 43062
Traceback (most recent call last):
File "test.py", line 5, in <module>
y = binascii.a2b_hqx(str(z))
binascii.Incomplete: String has incomplete number of bytes
And with this code:
y = binascii.a2b_hqx(bytearray(z))
This Traceback:
binascii.Error: Illegal char
What is generated is a checksum and not possible to convert back to ascii.
I want to pack 128 byte of different data types. The structure as follows
4 bytes - 0x12345678,
2 bytes - 0x1234,
120 bytes - 0x00 (repeats 120 times),
2 byte - 0x99 ,
I tried with below code but fails
struct.pack('<LH120BH',0x12345678,0x1234,0x00,0x99 )
gives error
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
struct.pack('<LH120BH',0x12345678,0x1234,0x00,0x99 )
struct.error: pack expected 123 items for packing (got 4)
pls help me. Thanks in advane
You may need to pack 0x00 in to an array if you want it to repeat 120 times and unpack it when call struct.pack, maybe something like this:
struct.pack('<LH120BH',0x12345678,0x1234,*[0x00] * 120,0x99)
Reading in a binary file and XORing bytes to find out if there is an AES 128 key present.
with open("FakeMemDump1.bin","rb") as memorydump:
mem = memorydump.read(memorybytes)
for i in mem:
w = mem[i]^mem[i+15]
x = mem[i+4]^mem[i+19]
y = mem[i+8]^mem[i+23]
z = mem[i+12]^mem[i+27]
if w==mem[i+16] and x==mem[i+20] and y==mem[i+24] and z==mem[i+28]:
keySched = mem[i-1:i+175]
print ("Key Schedule : "%keySched)
Traceback (most recent call last):
File "AES128Keyfind.py", line 8, in <module>
w = mem[i]^mem[i+15]
TypeError: string indices must be integers, not str
Above is the error I am receiving, is the byte being called passed in as a string even though the file is read as a binary file?
def main():
spiral = open('spiral.txt', 'r') # open input text file
dim = spiral.readline() # read first line of text
print(dim)
if (dim % 2 == 0): # check to see if even
dim += 1 # make odd
I know this is probably very obvious but I can't figure out what is going on. I am reading a file that simply has one number and checking to see if it is even. I know it is being read correctly because it prints out 10 when I call it to print dim. But then it says:
TypeError: not all arguments converted during string formatting
for the line in which I am testing to see if dim is even. I'm sure it's basic but I can't figure it out.
The readline method of file objects always returns a string; it will not convert the number into an integer for you. You need to do this explicitly:
dim = int(spiral.readline())
Otherwise, dim will be a string and doing dim % 2 will cause Python to try to perform string formatting with 2 as an argument:
>>> '10' % 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
>>>
Also, doing print(dim) outputed 10 instead of '10' because print automatically removes the apostrophes when printing:
>>> print('10')
10
>>>