上下文: 我使用python从flex应用程序解码amf响应。
使用pyamf,我可以解码所有响应,但有一个值引起了我的注意。
此值\ xa2C转换为4419
#\xa2C -> 4419
#\xddI -> 11977
我知道\ x与十六进制值有关,但我无法获得将4419转换为\ xa2C的函数。
4419是一个整数。
---更新1
此原始值不是十六进制。
因为我将此值\ xa2I转换为4425。
那么什么样的价值是\ xa2I ??? 谢谢!
- 更新2。
DJ = 5834
0F = 15
0G = error
1F = 31
a1f = 4294
adI = 5833
adg = 5863
adh = 5864
奇怪的是有些时候在F之后接受值并且在其他情况下显示错误。但是肯定不是十六进制值。
答案 0 :(得分:1)
您所看到的是AmfInteger
字节的字符串表示形式。第一个示例\xa2C
由两个字节组成:0xa2
又名162和C
,它是67的ASCII表示形式:
>>> ord("\xa2C"[0])
162
>>> ord("\xa2C"[1])
67
要将其转换为AmfInteger,我们必须遵循AMF3 specifications,第1.3.1节(AmfInteger的格式在AMF0和AMF3中是相同的,因此我们看到的规范无关紧要)。
在该部分中,U29(可变长度无符号29位整数,这是AmfIntegers在内部用来表示该值)被定义为1字节,2字节,3字节或4字节序列。每个字节编码有关值本身的信息,以及是否跟随另一个字节。要确定另一个字节是否跟随当前字节,只需要检查是否设置了最高有效位:
>>> (162 & 0x80) == 0x80
True
>>> (67 & 0x80) == 0x80
False
所以我们现在确认你看到的字节序列确实是一个完整的U29:第一个字节的高位设置,表示它后跟另一个字节。第二个字节的位未设置,表示序列的结束。要从这些字节中获取实际值,我们现在只需要组合它们的值,同时屏蔽第一个字节的高位:
>>> 162 & 0x7f
34
>>> 34 << 7
4352
>>> 4352 | 67
4419
由此可以很容易地弄清楚为什么其他值会给出您观察到的结果。
为了完整起见,这里还有一个Python代码片段,其中包含解析U29的示例实现,包括所有极端情况:
def parse_u29(byte_sequence):
value = 0
# Handle the initial bytes
for byte in byte_sequence[:-1]:
# Ensure it has its high bit set.
assert ord(byte) & 0x80
# Extract the value and add it to the accumulator.
value <<= 7
value |= ord(byte) & 0x7F
# Handle the last byte.
value <<= 8 if len(byte_sequence) > 3 else 7
value |= ord(byte_sequence[-1])
# Handle sign.
value = (value + 2**28) % 2**29 - 2**28
return value
print parse_u29("\xa2C"), 4419
print parse_u29(map(chr, [0x88, 0x00])), 1024
print parse_u29(map(chr, [0xFF, 0xFF, 0x7E])), 0x1ffffe
print parse_u29(map(chr, [0x80, 0xC0, 0x80, 0x00])), 0x200000
print parse_u29(map(chr, [0xBF, 0xFF, 0xFF, 0xFE])), 0xffffffe
print parse_u29(map(chr, [0xC0, 0x80, 0x80, 0x01])), -268435455
print parse_u29(map(chr, [0xFF, 0xFF, 0xFF, 0x81])), -127