0

I know this question has been asked before, and some of the suggestions seem to be about needing a b to make the string a byte literal. However, im passing hex code to the function as 0x414243 to save it as ABC.

def _pack(_data, size):
    numofbytes = size/8
    print("Chars Expected: " + str(numofbytes))
    formatString = "{}s".format(int(numofbytes))
    print("Formatted String:" + formatString)
    struct.pack(formatString,_data)

_pack(0x414243,24)

I'm not sure what to change here, im wondering if its a problem with how im using formatstring variable. I want the function to be able to work out how many chars are in the passed data from the size and in this case 24 bits = 3 bytes so it formats 3s and passes 0x414243 to convert to ABC.

Can anyone advise how to get past the error.

kindall
  • 178,883
  • 35
  • 278
  • 309
user1003967
  • 137
  • 2
  • 11

1 Answers1

0

As the error message says, struct.pack() wants a group of bytes and you're giving it an integer.

If you want to be able to pass the data in as an integer, convert it to bytes before packing it:

_data = _data.to_bytes(numofbytes, "big")   # or "little", depending on endianness

Or just pass the data in as bytes when you call it:

_pack(b"0x410x420x43", 24)

If you have a string containing hexadecimal, such as "0x414243", you can convert it to an integer, then on to bytes:

_data = int(_data, 16).to_bytes(numofbytes, "big")    

You might use isinstance() to allow your function to accept any of these formats:

if isinstance(_data, str):
    _data = int(_data, 16)
if isinstance(_data, int):
    _data = _data.to_bytes(numofbytes, "big")

By the way, your calculation of the number of bytes will produce a floating-point answer if size is not a multiple of 8. A fractional number of bytes is an error. To address this:

numofbytes = size // 8 + bool(size % 8)

The + bool(size % 8) bit adds one to the result of the integer division if there are any bits left over.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • nevermind i just re read you post. however when i pass it big i get output CBA when i pass it small i get \x00\x00\x00 how do i get the output ABC – user1003967 Feb 24 '18 at 00:57
  • The `b` tells Python how to parse a string literal; you can't "add it" programmatically. By the time you've written `"0x414243"` the data's already a string, not bytes. But you could parse it to an integer using `int(data, 16)` and then proceed as above to convert that integer to bytes. I'll add that. – kindall Feb 24 '18 at 01:02
  • Also if i make this changers and add abother char to the imput i.e 0x41424341 and pass 32 i get a memory error. – user1003967 Feb 24 '18 at 01:07