简体   繁体   中英

How to convert uint32_t to unsigned char array?

I'm trying to replicate conversion uint32_t values to unsigned char arrays in python (I've already done it in C)

This is my existing C function:

unsigned char *uint32_to_char_array(const uint32_t n)
{
    unsigned char *a;

    a = wrap_calloc(4, sizeof(unsigned char));

    a[0] = (n >> 24) & 0xff;  /* high-order (leftmost) byte: bits 24-31 */
    a[1] = (n >> 16) & 0xff;  /* next byte, counting from left: bits 16-23 */
    a[2] = (n >>  8) & 0xff;  /* next byte, bits 8-15 */
    a[3] = n         & 0xff;  /* low-order byte: bits 0-7 */

    return a;
}

If I were to do the following in gdb:

(gdb) p uint32_to_char_array(0x00240918)[0]@4  = "\000$\t\030"

And it's that string I'm trying to generate in python.

ie for a uint32_t input value of 0x240918 I want an output string of "\\000$\\t\\030"

I've scoured SO but to no avail thus far, particularly this -> How to convert integer value to array of four bytes in python but none of the answers seem to yield the input/output combination stated above

I'm using 2.7, but could use > 3.0 if required.

Update:

Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 0x240918.to_bytes(4, "big")
b'\x00$\t\x18'

Hmmm a bit different — I'm sure the answer is staring me in the face here but I can't see what it is?

So I can see:

>>> b"\000$\t\030"
b'\x00$\t\x18'

But how might one achieve the reverse? ie

>>> b'\x00$\t\x18'
b"\000$\t\030"

Maybe the question is how I can print a bytes-literal in octal rather than hexadecimal?

hmmm a bit different - i'm sure the answer is staring me in the face here but can't see what it is?

30 octal ie "\\030" is the same as 18 hexadecimal ie "\\x18" . Both of them represent a single byte in your byte sequence with a decimal value of 24.

You can compare the exact values in the REPL:

bytes((0x00240918 >> i & 0xff) for i in (24,16,8,0)) == b"\000$\t\030"
True

Check the Python documentation on string and byte literals :

  • \\ooo Character with octal value ooo
  • \\xhh Character with hex value hh

These can be used in byte literals as well as strings (keep in mind that strings are byte sequences in Python 2).

I don't think bytes support an octal representation by default (the ascii codec always uses hex), but you can code your own:

import re
my_b = b'\x00$\t\x18'
print(re.sub(r'\\x([0-9a-f]{2})', lambda a: "\\%03o" % int(a.groups()[0], 16),
  str(my_b)))
# Console result: b'\000$\t\030'

Keep in mind that the string contains verbatim quotes and the b' prefix, and it may accept escaped slashes as a hex sequence. If you really want a good octal __repr__ the best way would be to create a loop and check for non-printable characters, convert them to 3 digit octal and join everything into a string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM