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

时间:2018-01-18 10:41:57

标签: python hex ipv6

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

#                  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)这样的函数,但它总是以十进制形式返回,除非我写str(hex(tv)),但仍然有同样的问题,我不喜欢' t知道原始值是十六进制还是十进制。

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

---更新---

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

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

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

如果我写" print(str(line [3])"相反,输出相同。

2 个答案:

答案 0 :(得分:2)

前缀为0x的Python中的整数表示方式与非整数的整数相同。这意味着对于Python,0xFF 与255相同,并且没有办法区分它们;当您在hex base中工作时,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"],

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

或者将它作为整数存储,然后在想要将其显示为十六进制数时获取它们的十六进制表示。

答案 1 :(得分:-1)

使用int()可以很好地完成这项工作,Python会为您完成所有检查:)

int('00480065006C006C006F00200077006F0072006C00640021', 16)
6896377547970387516320582441726837832153446723333914657L

会奏效。如果失败,您将收到ValueError异常。

简短示例:

int('af', 16)
175

int('ah', 16)
 ...
ValueError: invalid literal for int() with base 16: 'ah'

来源:Check if a string is hexadecimal