我正在处理一个名为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])"相反,输出相同。
答案 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'