base64 - 高效的二进制到字符串格式(如 base64,但适用于 UTF8/UTF16)?

标签 base64 utf-16

我有很多二进制数据,范围从 16 到 4096 字节,需要存储到数据库中,并且应该作为一个单元很容易进行比较(例如,仅当长度匹配并且所有字节都匹配时,才可以比较两束数据匹配)。字符串对此很好,但盲目地将二进制数据转换为字符串很容易因字符编码/重新解释问题而导致问题。

在 7 位 ASCII 为常态的时代,Base64 是存储字符串的常用方法; 33% 的空间损失有点烦人,但并不可怕。不幸的是,如果使用 UTF-16,则空间损失为 166%(8 个字节存储 3 个字节),这看起来相当糟糕。

是否有任何通用的存储方法可以将二进制数据存储在有效的 Unicode 字符串中,从而在 UTF-16 中提高效率(并且希望在 UTF-8 中不会太糟糕)? Base-32768 编码将在 16 个字符中存储 240 位,这将占用 32 字节的 UTF-16 或 48 字节的 UTF-8。相比之下,base64 编码将使用 40 个字符,这将需要 80 字节的 UTF-16 或 40 字节的 UTF-8。设计为在 UTF-8 或 UTF-16 中占用相同空间的方法可能会在 3 个字符中存储 48 位,而在 UTF-8 或 UTF-16 中则需要 8 个字节,因此在 UTF-8 或 UTF-16 中的 40 个字节中存储 240 位-8 或 UTF-16。

有类似的标准吗?

最佳答案

Base32768正是你想要的。抱歉,它花了五年才存在。

用法(这是 JavaScript,尽管将 base32768 模块移植到另一种编程语言非常实用):

var base32768 = require("base32768");

var buf = new Buffer("d41d8cd98f00b204e9800998ecf842", "hex"); // 15 bytes

var str = base32768.encode(buf); 
console.log(str); // "迎裶垠⢀䳬Ɇ垙鸂", 8 code points

var buf2 = base32768.decode(str);
console.log(buf.equals(buf2)); // true

Base32768 从基本多语言平面中选择 32,768 个字符。每个字符在表示为 UTF-16 时占用 2 个字节,在表示为 UTF-8 时占用 3 个字节,这完全符合您所描述的效率特征:240 位可以存储在 16 个字符中,即 32 字节的 UTF-16 或 48 字节的 UTF- 8. (除了偶尔的填充字符,类似于 Base64 中的 = 填充。)

这是通过将输入字节(即 8 位无符号数)分割为 15 位无符号数并将每个生成的 15 位数分配给 32,768 个字符之一来完成的。

请注意,选择的字符也是“安全的” - 没有空格、控制字符、组合变音符号或对规范化损坏的敏感性。

关于base64 - 高效的二进制到字符串格式(如 base64,但适用于 UTF8/UTF16)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3998605/

相关文章:

适用于UTF-16LE和UTF32-LE的Unicode BOM

java - Apache commons IO 如何将我的 XML header 从 UTF-8 转换为 UTF-16?

Dart 从 base64 转换为 HEX

c# - 如何编码和解码 base64 字符串?

base64 - 使用notepad++将十六进制转换为Base64

python - lxml.etree.XMLSyntaxError,文档标记为 UTF-16 但具有 UTF-8 内容

javascript - 将所有不匹配的代理对替换为 JavaScript 字符串中的替换字符

BMP 之外的 JavaScript 字符串

javascript - IE9 - DataURI 到二进制 - .atob、Uint8Array 和 ArrayBuffer 的 Polyfills - 数组对于 polyfill 来说太大

php base64 图像错误 414(请求 URI 太大)