JSON字符串中的二进制数据。 比Base64更好的东西

JSON格式本身不支持二进制数据。 二进制数据必须转义,以便它可以放入JSON中的字符串元素(即使用反斜杠转义的双引号中的零个或多个Unicode字符)。

转义二进制数据的一个明显方法是使用Base64。 但是,Base64具有很高的处理开销。 它还将3个字节扩展为4个字符,导致数据量增加约33%。

其中一个用例是CDMI云存储API规范的v0.8草案。 您可以使用JSON通过REST-Webservice创建数据对象,例如

PUT /MyContainer/BinaryObject HTTP/1.1
Host: cloud.example.com
Accept: application/vnd.org.snia.cdmi.dataobject+json
Content-Type: application/vnd.org.snia.cdmi.dataobject+json
X-CDMI-Specification-Version: 1.0
{
    "mimetype" : "application/octet-stream",
    "metadata" : [ ],
    "value" :   "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
    IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
    dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
    dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
    ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=",
}

将二进制数据编码成JSON字符串有更好的方法和标准方法吗?


根据JSON规范(如果您的JSON以UTF-8传输),有94个Unicode字符可以表示为一个字节。 考虑到这一点,我认为你可以在空间上做的最好的是base85,它表示四个字节为五个字符。 然而,与base64相比,这仅仅提高了7%,计算起来更加昂贵,而实现不如base64更常见,所以它可能不是赢家。

您还可以简单地将每个输入字节映射到U + 0000-U + 00FF中的相应字符,然后执行JSON标准所需的最小编码以传递这些字符; 这里的优势在于,所需的解码在内建函数之外是零,但空间效率差 - 105%的扩展(如果所有输入字节的可能性相同),base85为25%,base64为33%。

最终裁决:在我看来,base64赢得胜利,理由是它很普通,容易,并且不够坏,不能更换。


我知道这是一个近6年的问题,但我遇到了同样的问题,并认为我会分享一个解决方案: multipart / form-data。

通过发送多部分表单,您首先以字符串形式发送您的JSON元数据,然后以Content-Disposition名称索引的原始二进制文件(图像,wavs等)单独发送。

这里有一个关于如何在obj-c中完成这个任务的很好的教程,这里是一篇博客文章,解释了如何使用表单边界对字符串数据进行分区,并将其与二进制数据分开。

你真正需要做的唯一改变是在服务器端; 你将不得不捕获你的元数据,它应该适当地引用POST'的二进制数据(通过使用Content-Disposition边界)。

授予它需要在服务器端进行额外的工作,但如果您发送的图像或大图像很多,这是值得的。 如果需要,可以将它与gzip压缩结合使用。

恕我直言,发送base64编码数据是一种破解; RFC multipart / form-data是针对以下问题创建的:将二进制数据与文本或元数据结合使用。


BSON(Binary JSON)可能适合您。 http://en.wikipedia.org/wiki/BSON

编辑:FYI .NET库json.net支持读取和写入bson,如果你正在寻找一些C#服务器端的爱。

链接地址: http://www.djcxy.com/p/3769.html

上一篇: Binary Data in JSON String. Something better than Base64

下一篇: Simple proof that GUID is not unique