我正在阅读MongoDB规范,它使用数据格式BSON
查看文档,我想了解其页面底部的BSON示例是如何编码的
{"hello": "world"} → "\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00"
{"BSON": ["awesome", 5.05, 1986]} → "\x31\x00\x00\x00\x04BSON\x00\x26\x00
\x00\x00\x020\x00\x08\x00\x00
\x00awesome\x00\x011\x00\x33\x33\x33\x33\x33\x33
\x14\x40\x102\x00\xc2\x07\x00\x00
\x00\x00"
答案 0 :(得分:1)
我认为问题基本上是“二进制协议如何工作”?或者`我如何阅读(伪)Backus-Naur-Form?
您可以这样想:您的协议包含用于构建数据的格式信息和数据本身。例如,您在JSON中看到的开头括号{
意味着“开始一个新的(子)文档”。
根据定义,这个'命令'是隐式的,只包含要遵循的所有内容的长度,然后是内容(e_list
),然后是\x00
终结符字节。因此,由于文档长度为22个字节(十六进制为0x16),因此“命令”为\x16\x00\x00\x00
。为什么这三个\x00
?因为我们需要一个int32,即一个32位整数,所以它必须填充到一个完整的四个字节。为什么\x16\x00\x00\x00
而不是\x00\x00\x00\x16
?这称为endianess,BSON使用little-endian。
然后是内容的定义,e_list
。 e_list
被定义为element
,后跟另一个e_list,该列表可以为空,然后终止。 element
首先定义为值的类型,然后定义e_name
,后跟实际数据。因此,由于"hello"
的值是"world"
,这是一个字符串,字符串由\x02
根据规范标识,{{1}接下来是\x02
“hello”和空终止符(e_name
)。
现在出现了一个字符串的实际值,它定义为hello\x00
,即字符串的长度,实际数据和空终止符(长度包括空终止符),所以长度变为int32 (byte*) "\x00"
,然后是顶级BSON文档的实际数据\x06\x00\x00\x00
和world\x00
终结符。