检查 python 中读取的值是十六进制还是十进制?

Check if a read value is hex or decimal in python?

我正在开发一个名为 SCHC 的 IPv6 header 压缩器,在我的代码中,我必须读取一个有时是十进制的值,有时是十六进制的值。我给你举个例子:

#                  fID                 pos  dir   tv                    mo         cda

rule = {"ruleid"  : 0,
     "content" : [["IPv6.version",      1,  "bi", 6,                  "equal", "not-sent"],
                  ["IPv6.trafficClass", 1,  "bi", 0x00,               "equal", "not-sent"],
                  ["IPv6.flowLabel",    1,  "bi", 0x000000,           "ignore", "not-sent"],
                  ["IPv6.payloadLength",1,  "bi", None,               "ignore", "compute-length"],
                  ["IPv6.nextHeader",   1,  "bi", 17,                 "equal", "not-sent"],
                  ["IPv6.hopLimit",     1,  "bi", 30,                 "equal", "not-sent"],
                  ["IPv6.prefixES",     1,  "bi", 0x200104701f1209f2, "equal", "not-sent"],
                  ["IPv6.iidES",        1,  "bi", 0x000000000000000b, "equal", "not-sent"],
                  ["IPv6.prefixLA",     1,  "bi", [0xFE80000000000000,
                                                  0x2001123456789012,
                                                  0x200104701f1209f2,
                                                  0x200141d004013100],"match-mapping", "mapping-sent"],
                  ["IPv6.iidLA",        1,  "bi", 0x0000000000003682, "equal", "not-sent"],
                  ["UDP.PortES",        1,  "bi", 5684,               "equal", "not-sent"],
                  ["UDP.PortLA",        1,  "bi", 5684,               "equal", "not-sent"],
                  ["UDP.length",        1,  "bi", None,               "ignore", "compute-length"],
                  ["UDP.checksum",      1,  "bi", None,               "ignore", "compute-checksum"],
                  ["CoAP.version",      1,  "bi", 1,                  "equal", "not-sent"],
                  ["CoAP.type",         1,  "up", 0,                  "equal", "not-sent"],
                  ["CoAP.type",         1,  "dw", 2,                  "equal", "not-sent"],
                  ["CoAP.tokenLength",  1,  "bi", 1,                  "equal", "not-sent"],
                  ["CoAP.code",         1,  "up", 2,                  "equal", "not-sent"],
                  ["CoAP.code",         1,  "dw", [69, 132],          "match-mapping", "mapping-sent"],
                  ["CoAP.messageID",    1,  "bi", 0,                  "MSB(12)", "LSB"],
                  ["CoAP.token",        1,  "bi", 0x80,               "MSB(4)", "LSB"],
                  ["CoAP.Uri-Path",     1,  "up", "foo",              "equal", "not-sent"],
                  ["CoAP.Uri-Path",     2,  "up", "bar",              "equal", "not-sent"],
                  ["CoAP.Uri-Path",     3,  "up", None,               "ignore", "value-sent"],
                  ["CoAP.Content-Format",1, "dw", None,               "ignore", "value-sent"],
                  ["CoAP.Uri-Query",    1,  "up", "k=",               "MSB(16)", "LSB"],
                  ["CoAP.Option-End",   1,  "up", 0xFF,               "equal", "not-sent"]
               ]}

这是 SCHC 的规则压缩示例。如您所见,tv(目标值)字段有时可以是整数、字符串、数组……对于整数,它们可能具有十进制或十六进制表示形式。我想做的是在字符串中重写该整数的值,但我的问题是,当我访问该值时,我无法知道它是十六进制还是十进制。

我已经尝试了很多东西,比如正则表达式,使用像 str(tv) 这样的函数,但是它 returns 总是十进制,除非我写 str(hex(tv)),但仍然有同样的问题我不知道原始值是十六进制还是十进制。

提前谢谢你,我希望我的解释很清楚!

---更新---

所以,如果我在声明变量后立即执行类似的操作 "rule",

for line in rule['content']:
  fID,pos,di,tv,mo,cda = line
  print(line[3])

打印的输出将是 IPv6.prefixES 行中的“2306129363794528754”,而不是 0x200104701f1209f2。

如果我改写 "print(str(line[3])",会完成相同的输出。

Python 中以 0x 为前缀的整数在幕后表示的方式与不是整数的方式相同。这意味着对于 Python,0xFF 与 255 相同,并且无法区分它们; 0x 只是在您使用十六进制时描述整数的一种便捷方式。 0b 也是如此,二进制表示。

因此,无法像代码中那样区分它们。在 REPL 中尝试以下操作:

>>> 0xFF == 255
True
>>> isinstance(255, int)
True
>>> isinstance(0xFF, int)
True
>>> 0xFF
255
>>> 0b11111111 == 0xFF == 255
True

你的正则表达式不起作用,因为正则表达式需要一个字符串;当它看到您的整数时,它会将 int 转换为字符串,但由于默认表示形式是将整数转换为以 10 为底的整数,因此它看起来就是这样:一个以 10 为底的整数。

你的解决方案是将十六进制值实际存储为字符串,然后在你真正想要使用它们时将它们转换回整数,即:

["IPv6.prefixES", 1, "bi", "0x200104701f1209f2", "equal", "not-sent"],

(注意引号表示它是一个字符串)

或者像您一样将其存储为整数,然后在您想将其显示为十六进制数时获取它们的十六进制表示形式。