MessagePack

官网的介绍: It’s like JSON. but fast and small.

../_images/messagepack-intro.png

MessagePack 也是一种紧凑的二进制序列化格式, 支持流式序列化,非常适合RPC传输, 编解码速度、占用空间和 Protobuf 一个量级,其优势是 schema-less , 可以灵活地传输各种数据。

主要编码范式也是 type+length+data 以及 type+data。 但实现数据紧凑的方式和 Protobuf 有所不同,Protobuf 使用首位标识后面是否有数据, 而 MessagePack 通过类型系统决定整数有多长,如 uint8 存放小整数,uint16 类型存放大整数。

1 byte 类型

这类type本身就是一个值,没有data,只需要 type 字段就能表示。

这个分类只有三种类型: nil、true、false 。

如 nil (type 是 0xc0):

+--------+
|  0xc0  |
+--------+

数值类型

数值类型编码范式是 type+data

根据数值大小自动选择 int8/int16/int32/int64 ,从而节省空间。

如 uint 16(type 是 0xcd):

+--------+--------+--------+
|  0xcd  |ZZZZZZZZ|ZZZZZZZZ|
+--------+--------+--------+

这里就有必要介绍 MessagePack 另一个创新之处: type 内部也能存储数据。 对于太小的整数(0~127), 其值可以直接存储在 type 里面,放在后 7 位。

如 uint7:

+--------+
|0XXXXXXX|
+--------+

所以数值 1 的编码为:

+--------+
|00000001|
+--------+

可变类型

字符串一般范式是 type length data。和数值类型一样,对于超短的字符串,length/type 可以存储在一个 byte 里面。

长度小于 31 的字符串:

+--------+========+
|101XXXXX|  data  |
+--------+========+

长度在 (2^8)-1 以内的字符串:

+--------+--------+========+
|  0xd9  |YYYYYYYY|  data  |
+--------+--------+========+

以此类推……

所有编码类型

format name first byte (in binary) first byte (in hex)
positive fixint 0xxxxxxx 0x00 - 0x7f
fixmap 1000xxxx 0x80 - 0x8f
fixarray 1001xxxx 0x90 - 0x9f
fixstr 101xxxxx 0xa0 - 0xbf
nil 11000000 0xc0
(never used) 11000001 0xc1
false 11000010 0xc2
true 11000011 0xc3
bin 8 11000100 0xc4
bin 16 11000101 0xc5
bin 32 11000110 0xc6
ext 8 11000111 0xc7
ext 16 11001000 0xc8
ext 32 11001001 0xc9
float 32 11001010 0xca
float 64 11001011 0xcb
uint 8 11001100 0xcc
uint 16 11001101 0xcd
uint 32 11001110 0xce
uint 64 11001111 0xcf
int 8 11010000 0xd0
int 16 11010001 0xd1
int 32 11010010 0xd2
int 64 11010011 0xd3
fixext 1 11010100 0xd4
fixext 2 11010101 0xd5
fixext 4 11010110 0xd6
fixext 8 11010111 0xd7
fixext 16 11011000 0xd8
str 8 11011001 0xd9
str 16 11011010 0xda
str 32 11011011 0xdb
array 16 11011100 0xdc
array 32 11011101 0xdd
map 16 11011110 0xde
map 32 11011111 0xdf
negative fixint 111xxxxx 0xe0 - 0xff