【问题标题】:How to convert uint32_t to unsigned char array?如何将 uint32_t 转换为无符号字符数组?
【发布时间】:2019-05-08 20:18:26
【问题描述】:

我正在尝试在 python 中将转换 uint32_t 值复制到 unsigned char 数组(我已经在 C 中完成了)

这是我现有的 C 函数:

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;
}

如果我在 gdb 中执行以下操作:

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

这就是我试图在 python 中生成的字符串。

即对于uint32_t 输入值0x240918 我想要一个输出字符串"\000$\t\030"

我已经搜索了 SO,但到目前为止无济于事,尤其是这个 -> How to convert integer value to array of four bytes in python 但似乎没有一个答案会产生上述输入/输出组合

我使用的是 2.7,但如果需要,可以使用 > 3.0。

更新:

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'

嗯,有点不同——我敢肯定,答案就在眼前,但我看不出它是什么?

所以我可以看到:

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

但是如何实现相反的效果呢?即

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

也许问题是我如何以八进制而不是十六进制打印字节文字?

【问题讨论】:

  • to_bytes 对您确定的问题的回答似乎很合适:0x240918.to_bytes(4, "big") == b"\000$\t\030" 在 Python 3.7 上给了我Truestruct.pack('>I', 0x240918) 也可以。
  • 您链接的解决方案是完全相同的代码。 bytes((0x00240918 >> i & 0xff) for i in (24,16,8,0)) == b"\000$\t\030" 是真的。
  • 请注意,b'\x00$\t\x18'b"\000$\t\030" 是同一字符串的不同表示形式。
  • 宾果游戏!我怎样才能从一个切换到另一个?即让我的系统打印 b"\000$\t\030" 而不是 b'\x00$\t\x18'?

标签: python c arrays uint32-t


【解决方案1】:

嗯有点不同 - 我确定答案正盯着我看,但看不到它是什么?

30 八进制即"\030" 与 18 十六进制相同,即"\x18"。它们都代表字节序列中的一个字节,十进制值为 24。

您可以比较 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八进制字符ooo
  • \xhh 十六进制值 hh 的字符

这些可以用于字节文字和字符串(请记住,字符串是 Python 2 中的字节序列)。

我认为bytes 默认不支持八进制表示(ascii 编解码器始终使用十六进制),但您可以编写自己的代码:

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'

请记住,字符串包含逐字引号和b' 前缀,并且它可以接受转义的斜杠作为十六进制序列。如果你真的想要一个好的八进制 __repr__ 最好的方法是创建一个循环并检查不可打印的字符,将它们转换为 3 位八进制并将所有内容连接成一个字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多