使用非 Qt 从 Qt QJsonDocument::toBinaryData 读取二进制 Json?

Posted

技术标签:

【中文标题】使用非 Qt 从 Qt QJsonDocument::toBinaryData 读取二进制 Json?【英文标题】:Read Binary Json from Qt QJsonDocument::toBinaryData using non-Qt? 【发布时间】:2018-08-21 19:38:58 【问题描述】:

我有以下 JSON 结构:

"
    "dateTime": "02/06/2016 - 13:01:06",
    "event": 12344,
    "eventOwner": "1",
    "condition": "",
    "ownerParent": "",
    "sn": "0000000000"
"

我使用 Qt 框架 QJsonDocument::toBinaryData() 函数将其写为二进制文件头/水印。

但是,我无法将它从 python 和/或标准 c++ 解析回来,以便再次使用 JSON。

Qt 似乎也在这个二进制数据上写入了一个标头,标记为“qbjs1”,然后是 rawData(Qt Binary JSON 版本 1)。

但是,有一些 '\0' 导致无法将二进制数据解析为 JSON。如下:

来自 JSON 二进制数据的 hexdump:

00000000  71 62 6a 73 01 00 00 00  c0 00 00 00 0d 00 00 00  |qbjs............|
00000010  a8 00 00 00 9b 03 00 00  08 00 64 61 74 65 54 69  |..........dateTi|
00000020  6d 65 00 00 15 00 30 32  2f 30 36 2f 32 30 31 36  |me....02/06/2016|
00000030  20 2d 20 31 33 3a 30 31  3a 30 36 00 1a f3 02 00  | - 13:01:06.....|
00000040  06 00 65 76 65 6e 74 1b  0d 00 00 07 00 65 76 65  |..event......eve|
00000050  6e 74 4f 77 6e 65 72 00  00 00 08 00 31 00 00 1b  |ntOwner.....1...|
00000060  0e 00 00 0b 00 63 6f 6e  64 69 74 69 6f 6e 00 00  |.....condition..|
00000070  00 00 00 00 00 1b 10 00  00 06 00 6f 77 6e 65 72  |...........owner|
00000080  50 61 72 65 6e 74 0b 00  34 35 20 66 6f 72 6b 65  |Parent..45 forke|
00000090  64 00 00 00 9b 13 00 00  05 00 73 6e 00 0d 00 30  |d.........sn...0|
000000a0  30 30 30 30 30 30 30 30  30 0c 00 00 00 34 00 00  |000000000....4..|
000000b0  00 40 00 00 00 5c 00 00  00 74 00 00 00 90 00 00  |.@...\...t......|
000000c0  00 0d                                             |..|
000000c2

如何使用非 QT C++ 和 python 解析这些二进制数据?

【问题讨论】:

docs:二进制表示也是Qt内部使用的原生格式,转换起来非常高效快速。说它是内部的意味着您可以在不事先通知的情况下从一个版本更改为另一个版本,因此没有单一的方法可以做到这一点,这类似于 QDataStream 发生的情况。 由于这不是标准格式,而是 Qt 独有的特殊格式,因此很有可能没有非 Qt 库来解析它。如果格式记录在某处,您可以根据该文档自己编写一个。如果没有,您可以通过阅读 Qt 源代码对其进行逆向工程,但这可能会使您承担他们许可的义务,或者您可以从第一原理对其进行逆向工程。 您是否有理由不能只编写一个简单的工具,使用 Qt 在 Qt-binary-JSON 中流式传输并输出真正的 JSON,反之亦然,并通过该工具从非 Qt C++ 或 Python 程序? 顺便说一句,据我快速扫描得知,\0 字节主要用于填充内容,以便除字符串之外的所有内容都处于固定或易于计算的状态抵消。这大概就是它“不那么节省空间……但访问速度更快”的原因。 【参考方案1】:

由于这不是标准格式,而是 Qt 独有的特殊格式,因此可能没有非 Qt 库可以解析它。

此外,由于它是未记录的并且是内部的,因此无法保证它在 Qt 的各个版本之间都是相同的。1

如果您愿意阅读 Qt 源代码(确保它不会对您施加任何您不想要的许可限制),那么 src/corelib/serialization/qjson_p.h 中似乎已经很好地记录了该格式。因此,您可以为这种格式编写自己的解析器。您甚至可以从 serialization 目录的其余部分借用源代码来完成大部分工作。

否则,唯一的选择是通过查看各种 JSON 和 Qt-binary-JSON 等效项并弄清楚每种值如何存储来对其进行逆向工程。 (它不能太复杂;JSON 并没有太多...)


1。事实上,源代码中的文档有一个很大的明确警告:“这个文件不是 Qt API 的一部分。它纯粹作为一个实现细节存在。这个头文件可能会在没有通知的情况下从一个版本到另一个版本更改,甚至被删除。 "

【讨论】:

以上是关于使用非 Qt 从 Qt QJsonDocument::toBinaryData 读取二进制 Json?的主要内容,如果未能解决你的问题,请参考以下文章

Qt 和 JSON 资源解析 - 空 QJSONDocument

QT软件开发: 解析JSON数据(QJsonX)

QT学习_QT解析Json格式文件

在Qt中使用QJsonDocument解析嵌套的JSON

如何将多个 QJsonObject 添加到 QJsonDocument - Qt

QJsonDocument实现Qt下JSON文档读写