我有一个字节数组,需要将其存储到
nvarchar
数据库列中。一个 nvarchar
占用 2 个字节。最佳编码是什么?
理想情况下,我会将 N 个字节存储到长度为 N/2 的
nvarchar
中,但存在无效的 unicode 序列让我担心。
最佳解决方案是将二进制存储在二进制列中。那么您的意思是在这种次优场景的约束下的最佳编码?
就用base64吧,很安全。
如果无法控制输入字节,迟早会遇到编码问题。
通常 Base64 是一个好方法,但您可以只使用 Unicode 代码点。
Unicode 代码点从 0 到 10FFFF,但您可以轻松高效地将 2 个半字节编码为 Unicode 代码点。根据您的要求,您可以将所有代码点移动 128,以便您有 ASCII 边界(并且您不需要担心字节 0,并且仍然有足够的代码点用于 20 位二进制数据(每个代码点)。 [或者可能只是将 0 转义为 0x10000]
对于 Unicode,这是通用的(所以通用 Unicode)。如果您知道编码(例如UTF-8,您可以选择不同的编码)。
查看 Unicode 规范(版本 16)中的表 3-6 和 3-7:
标量值 | 第一个字节 | 第二个字节 | 第三个字节 | 第四个字节 |
---|---|---|---|---|
00000000 0xxxxxxx | 0xxxxxxx | |||
00000yyyyyxxxxxx | 110yyyyy | 10xxxxxx | ||
zzzzyyyyyyxxxxxx | 1110zzzz | 10yyyyyy | 10xxxxxx | |
000uuuuu zzzzyyyyyyxxxxxx | 11110uuu | 10uuzzz | 10yyyyyy | 10xxxxxx |
表 3-6 指定了 UTF-8 编码形式的位分布,显示了与一、二、三和四字节序列对应的 Unicode 标量值的范围。
代码点 | 第一个字节 | 第二个字节 | 第三个字节 | 第四个字节 |
---|---|---|---|---|
U+0000..U+007F | 00..7F | |||
U+0080..U+07FF | C2..DF | 80..BF | ||
U+0800..U+0FFF | E0 | A0..BF | 80..BF | |
U+1000..U+CFFF | E1..EC | 80..BF | 80..BF | |
U+D000..U+D7FF | ED | 80..9F | 80..BF | |
U+E000..U+FFFF | EE..EF | 80..BF | 80..BF | |
U+10000..U+3FFFF | F0 | 90..BF | 80..BF | 80..BF |
U+40000..U+FFFFF | F1..F3 | 80..BF | 80..BF | 80..BF |
U+100000..U+10FFFF | F4 | 80..8F | 80..BF | 80..BF |
表 3-7 列出了 UTF-8 中格式正确的所有字节序列。诸如 A0..BF 之类的字节值范围表示从 A0 到 BF(含)的任何字节在该位置都是格式良好的。超出列出范围的任何字节值都是格式错误的。
在表 3-7 中,尾随字节范围不是 80..BF 的情况以粗体斜体显示,以引起注意。一般模式的这些例外仅发生在序列的第二个字节中。
只要你不超出这些限制,我相信你应该没问题。如果你只用它来存储二进制数据,不会以文本形式显示,你不必担心非字符、控制字符和奇怪的字符,这些字符可能会把事情搞砸。