AMF 格式分析

1解析打包后的数据头部

00000000  00 03 00 00 00 01 00 1d 45 78 61 6d 70 6c 65 53           ExampleS
00000010  65 72 76 69 63 65 2f 72 65 74 75 72 6e 4f 6e 65   ervice/returnOne
00000020  50 61 72 61 6d 00 02 2f 31 00 00 00 3d 0a 00 00   Param  /1   =  
00000030  00 01 11 0a 0b 0d 6d 79 54 79 70 65 11 61 72 72         myType arr
00000040  61 79 56 61 6c 09 07 01 04 01 04 02 06 07 65 72   ayVal         er
00000050  74 13 73 74 72 69 6e 67 56 61 6c 06 07 62 6c 61   t stringVal  bla
00000060  0d 69 6e 74 56 61 6c 04 02                        intVal
  1. 两个字节的版本标记:00 03,也可能是 00 00,BE 编码。
  2. 两个字节的头部小节数量:00 00 ,BE编码。如果不为00,则后面跟具体的头部小节信息。这里为0,每个小节的格式为:
    [小节名称:[16位BE编码长度][UTF-8编码字符串内容]][8位布尔值, must-understand 标记][32位BE编码小节长度][AMF 0 值]
  3. 两个字节的消息内容数据数量:00 01,BE编码。这里 00 01 转换后的结果就是 1,也就是说这个头部表明有 1 个数据结点。接下来是多个数据体列表,每个数据体的格式如下:
    (1)、请求的目标服务名称:[16位BE编码字符串长度][UTF-8编码字符串内容];
    (2)、服务响应名称:[16位BE编码字符串长度][UTF-8编码字符串内容];
    如上面请求的目标服务名称部分为:00 1d 45 78 61 6d 70 6c 65 53 65 72 76 69 63 65 2f 72 65 74 75 72 6e 4f 6e 65 50 61 72 61 6d,00 1d 就是名称的长度 29,后面 29 个 UTF-8 编码的字符构成实际的值:ExampleService/returnOneParam。同理,后面的响应名称 00 02 2f 31 对应的是长度为 2 字节的字符串 /1。
    (3)、32位BE编码的的数据体长度 00 00 00 3d ,也就是说本数据体占用的空间是 61 字节。
    (4)、AMF 0 格式的数据体内容。

这里注意一个问题,AMF 数据打包是按照 AMF 0 标准来打包的,所以虽然头部版本号是 00 03,头部和消息的数据体依然是默认按 AMF 0 来开始解析,直到你遇到了类型为 11 (十进制 17 )的类型标记,以它标记的数据才是 AMF 3 格式的。我们以上面的数据内容做一下人工解析: 

0a 00 00 00 01 11 0a 0b 0d 6d 79 54 79 70 65 11 61 72 72 61 79 56 61 6c 09 07 01 04 01 04 02 06 07 65 72 74 13 73 74 72 69 6e 67 56 61 6c 06 07 62 6c 61 0d 69 6e 74 56 61 6c 04 02
  • 0a :AMF 0 数组(10)
    • 00 00 00 01 :数组元素数量为 1 ;
    • 11 :切换成 AMF 3 对象(17)
      • 0a :自身类型为 AMF 3 对象(10)
      • 0b:一个 AMF 3 整数类型,用于做对象标志位(11,二进制 1011:[类型属性数量:25位][动态类型标志][外部类型标志][内置类声明标志][内置对象标志]),这是一个动态、内置类声明的动态类型。剩下的位数为0,所以这个类型没有子类型属性。如果有,则根据 AMF3 的字符串规则,读取每一个属性名称字符串。
      • 0d:一个 AMF 3 整数类型,用于做类型名称长度(13,根据AMF 3 字符串规则,实际长度为 6 字节)
      • 6d 79 54 79 70 65:UTF-8 编码的类型名称(myType)
      • 11 61 72 72 61 79 56 61 6c :属性名称的 AMF 3 字符串(arrayVal)
        • 09:arrayVal 属性的值类型为 AMF 3 数组
        • 07:一个 AMF 3 整数类型,用于做数组标志位,最低位是数组是否内置标志,剩下的是实际的普通数组元素个数(3),用字符串做键值的数组元素不在此列。
        • 01:数组元素的键值为 0 长度的 AMF 3 字符串(低位是引用标志位),如果不为0,需要循环读取直到内容字符串内容为空。
        • 04 01:元素类型为整数值 01
        • 04 02:元素类型为整数值 02
        • 06 07 65 72 74:AMF3 字符串 ert(后面不再详解)
      • 13 73 74 72 69 6e 67 56 61 6c:属性名称为 AMF 3 字符串 stringVal
        • 06 07 62 6c 61 :AMF 3 字符串 bla
      • 0d 69 6e 74 56 61 6c:属性名称为 AMF 3 字符串 intVal
        • 04 02 :元素内容为整数值 02、

2基本数据类型

AMF 格式的数据类型分为两种,一种是 AMF 0 规定的数据类型,另一种就是 AMF 3 规定的数据类型。它们之间是通过 AMF0 中一个特殊的类型 0x11 (类型编码为 17)来进行转换的。也就是说,在按 AMF 0 解析内容时,如果遇到类型的编码为 0x11 的项目,那就说明这个项目是 AMF3 格式的对象了,我们需要按 AMF 3 格式对其内容进行解析。

先看 AMF 0 的数据类型( 2006 版):

  • 0 :布尔类型,1 代表真,0 代表假;
  • 1 :双精度浮点数,格式为标准的Doube类型的 BE 编码表示,我们用时需要转换字节度;
  • 2 :短字符串,最长是65535字节;前两个字节是一个16 位 BE 编码的整数,代表后面的 UTF-8 字符串内容的长度。
  • 3:对象
  • 4:视频剪辑
  • 5:NULL
  • 6:未定义
  • 7:引用
  • 8:混合数组
  • 9:对象结束
  • 10:普通数组
  • 11:日期时间
  • 12:长UTF-8字符串,头32位整数代表字符串长度
  • 13:Action Script 对象
  • 14:数据集
  • 15:XML 字符串
  • 16:用户定义类型
  • 17:AMF 3 格式对象

再看 AMF 3 的类型( 2013 版):

  • 0:未定义
  • 1:NULL
  • 2:假
  • 3:真
  • 4:最大 29 位整数(U29)
  • 5:双精度浮点数
  • 6:UTF-8字符串,以一个U29整数来表示字符串长度,后跟内容
  • 7:XML 文档
  • 8:日期时间类型
  • 9:数组
  • 10:对象
  • XML:XML 字符串
  • 12:字节流
  • 13:整型向量
  • 14:无符号整数向量
  • 15:双精度浮点数向量
  • 16:对象向量
  • 17:字典

为啥 AMF3 会有两个 XML 支持,这个问 Adobe 去,反正不是我规定的。每个 AMF 格式的数据实际上都是有一个一个字节的类型标志开始,后跟这个类型格式约定的具体值。

3数据类型存贮格式详解

1、双精度浮点数

类型编号:0

格式:IEEE-754 的8字节 BE 编码

2、布尔

类型编号:1

格式:单字节

备注:0 为 false,其它值为 true

3、字符串

类型编号:2

格式:[字符串长度][字符串内容]

备注:字符串长度为两个字节的 WORD 类型(BE编码),字符串内容是 UTF-8 编码

4、对象类型

类型编号:3

格式:[[属性名称][对象结束类型标记|属性值]]…

备注:首先是第一个属性的名称,然后是属性的值或者对象结束标记(09),如果遇到对象结束标记,则对象属性定义结束。

5、视频剪辑

类型编号:4

格式:官方未提供支持

6、NULL 类型

类型编号:5

格式:无附加内容

7、未定义类型(Undefined)

类型编号:6

格式:无附加内容

8、引用类型

类型编号:7

格式:引用的复合类型索引(匿名对象、特定类型对象、数组或混合数组,BE编码)

9、复合数组

类型编号:8

格式:[元素数量][元素*元素数量]

备注:元素数量为32位无符号整数,后面跟每一个元素的定义

10、对象结束

类型编号:9

格式:00 00

备注:可以认为是长度为 0 的 UTF8 字符串,应用于对象和数组等复合类型

11、严格数组

类型编号:10

格式:[元素数量][元素*元素数量]

备注:元素数量为 32 位无符号整数,后面跟每个元素的定义,与复合数组不同,它没有额外的索引内容

12、日期类型

类型编号:11

格式:[日期值][00 00]

备注:日期值为1970-1-1 午夜开始的毫秒数,类型为双精度浮点数(BE 编码)

13、长字符串

类型编号:12

格式:[字符串长度][字符串内容]

备注:字符串长度为 32 位整数,后跟对应长度的 UTF-8 字符串内容

14、不支持的类型

类型编号:13

格式:官方未提供支持

15、数据集类型

类型编号:14

格式:官方未提供支持

16、XML

类型编号:15

格式:[内容长度][内容]

备注:内容长度为 32 位整数,后跟对应长度的 UTF-8 格式内容

17、特定类型对象

类型编号:16

格式:[类型名称][对象类型-对象值]*

备注:

18、AMF 3 对象

类型编号:17

格式:[AMF 3 数据类型定义]

备注:这个类型定义到对象类型定义结束,都是 AMF 3 格式。

转载于:https://my.oschina.net/yan5845hao/blog/692474

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值