1

I am in the process of bringing an API up from 2.7 to 3.8. It is built to communicate with an agent over a TCP socket. I am having an issue with a checksum not being calculated right. I get a message back from my agent that the Checksum is bad.

I know it is not my agent because the CRC check on header only packets are being accepted and the commands are executed correctly on the agent side.

The line of code I am having an issue with is:

body += format(struct.pack("=L", binascii.crc32(format(body).encode()) & 0xFFFFFFFF))

Previously on 2.7 this line of code had no encoding/formatting.

Does anyone know what I am doing wrong?

I have a strong feeling it pertains to the encoding of 'body string'. After breaking the line of code down to its components I confirmed that the int output of binascii.crc32() is different between 3.8 and 2.7 and doing a bit of reading on the variety of byte/char types there are I have become quite lost.

mattmccj
  • 11
  • 2
  • 1
    This code produces a `SyntaxError: cannot assign to literal`. Please provide a working example together with the actual output and the expected output. Or is the SyntaxError your actual problem? If so, please state that and share the original code that worked together with the output it produced. – Wombatz Mar 18 '21 at 11:26
  • I changed it to a variable. I was just trying to make it clear that the input was a string and then subsequently I appended the checksum to the string to be sent out. to be clear I am not getting any errors in my code I just know that I am computing the wrong checksum. Ill add example output shortly. – mattmccj Mar 18 '21 at 11:53
  • What are these calls to `format` supposed to do? They don't seem correct. Regarding the CRC, I'm assuming it's supposed to be a checksum of the data that was sent over TCP. In which case you should calculate the CRC of the `bytes` you're sending instead of doing encoding here. – interjay Mar 18 '21 at 11:55
  • the format("string").encode() call is to encode the string as a byte string so that crc32 can calculate the checksum then the int output has to be translated back into a string to be added to the packet (body). later it is encoded into bytes again and added to the header and sent. – mattmccj Mar 18 '21 at 12:03
  • `format("string")` just gives `"string"`. And `format(bytes_object)` (as you're doing with the result of `struct.pack`) is almost certainly wrong. As I explained above, you should be working with bytes, not strings. – interjay Mar 18 '21 at 12:19
  • @interjay thank you I got rid of the format(byte_object) and dumped the body and checksum right on to the buffer and that worked. – mattmccj Mar 18 '21 at 12:40
  • @Wombatz I appreciate you pushing me to isolate this string of code I realized that I also had an issue with the extraction of the string from json. some how between versions of json the extraction of variables got inverted and was causing the bulk of my problem. – mattmccj Mar 18 '21 at 12:42

1 Answers1

0

so the correct line of code is to append the checksum and body to the packet buffer simultaneously rather than add the checksum to the body and then add the body to the packet buffer. this avoids a decoding stage that was causing an issue.

buf = buf + format(body).encode() + struct.pack("=L", binascii.crc32(format(body).encode()) & 0xFFFFFFFF)

the original would output: '{"datasetName": "X_train", "fileName": "/test/MNIST/X_train_uint8.h5"}b\'y\\xf8D\\xec\''

the correct solution seen in this answer outputs: '{"datasetName": "X_train", "fileName": "/test/MNIST/X_train_uint8.h5"}y\xf8D\xec'

mattmccj
  • 11
  • 2