6

我有很多二进制数据,从 16 到 4096 字节不等,它们需要存储到数据库中,并且应该很容易作为一个单元进行比较(例如,只有长度匹配且所有字节匹配的两束数据批)。字符串对此很好,但是由于字符编码/重新解释问题,盲目地将二进制数据转换为字符串很容易引起问题。

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

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

有这样的标准吗?

4

1 回答 1

5

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 个字符中,即 UTF-16 的 32 个字节或 UTF-16 的 48 个字节8. (除了偶尔的填充字符,类似于=在 Base64 中看到的填充。)

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

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

于 2016-04-18T22:05:38.430 回答