0

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

4

1 回答 1

1

您所看到的是字节的字符串表示形式AmfInteger。第一个示例\xa2C由两个字节组成:0xa2又名 162 和C,它是 67 的 ASCII 表示:

>>> ord("\xa2C"[0])
162
>>> ord("\xa2C"[1])
67

要将其转换为 AmfInteger,我们必须遵循AMF3 规范,第 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
于 2016-03-08T16:29:59.410 回答