我如何将此值转换为十六进制? (amf值)

时间:2016-03-07 13:02:02

标签: python hex amf pyamf

上下文: 我使用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之后接受值并且在其他情况下显示错误。但是肯定不是十六进制值。

1 个答案:

答案 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