在UTF-8字符串中存储二进制数据

23

我想使用WebSocket传输二进制数据,但是WebSocket仅支持传输UTF-8字符串。

使用base64进行编码是一种选择,但我的理解是,当您的文本可能从一种格式转换为另一种格式时,base64是最理想的选择。在这种情况下,我知道数据将始终为UTF-8,因此是否有更好的方法在UTF-8字符串中编码二进制数据而不付出base64 33%的大小溢价?

这个问题主要是学术性质的,因为WebSocket很可能会最终添加对二进制数据的支持,并且在此期间,base64是一个完美的替代方案。


3
+1 好问题,有之前的研究 :) - alex
5
WebSocket规范现在包含二进制支持:http://www.w3.org/TR/websockets/#dom-websocket-send - Janus Troelsen
3个回答

16
你可以使用基于128进制的编码替代64进制编码。相比之下,这只会增加1/7的开销而不是1/3。
思路是使用UTF-8中可以用单个字节表示的所有Unicode码点(0-127)。这意味着所有字节都以0开头,因此还有七个位可供数据使用。
0‍xxxxxxx

这会导致一种编码方式,即使用8个输出字节对7个输入字节进行编码:

input:  aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg
output: 0aaaaaaa 0abbbbbb 0bbccccc 0cccdddd 0ddddeee 0eeeeeff 0ffffffg 0ggggggg

因此,输出与输入的比率为8/7。


1
我认为我已经按照你的描述实现了。这是它的连接:https://gist.github.com/3881249。 - Janus Troelsen

0

当字符串不支持二进制 Blob 且文本编码可能会发生更改时,Base64 最好使用。通常在所有字符集中都可以安全使用 Base64 中使用的字符(已经存在很长时间)。

如果您知道它始终是 UTF8,请以一种利用许多数千个 UTF8 字符的方式对其进行编码?


4
我认为这个答案基本上与原问题相同。 - Zach

0

您也可以使用Base-91。最坏情况下的开销为23%。Base-128为1/7 = 14%。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接