二进制到字符串为二进制?

4 .net c# string binary bytearray

Redis密钥是二进制安全的.我想乱用并使用C#将二进制文件放入redis.我选择的客户端不支持编写使用密钥的二进制密钥,这是有意义的.但是我只是在鬼混,所以告诉我如何才能做到这一点.

如何将原始字节[]转换为字符串?起初我正在考虑将byte []转换为utf8字符串,但unicode有一些检查是否有效.原始二进制文件应该失败

其实我试了一下.而不是失败我得到一个奇怪的结果.我的主要问题是如何将原始转换为byte[]等效字符串?因为将原始byte []作为字符串而不是编码为base32/64/hex/whatever.我不重要的问题是为什么我得到一个512字节的字符串而不是一个异常,说这不是一个有效的UTF8字符串?

var rainbow = new byte[256];
for (int i = 0; i < 256; i++)
{
    rainbow[i] = (byte)i;
}
var sz = Encoding.UTF8.GetString(rainbow);
var szarr = Encoding.UTF8.GetBytes(sz);
Console.WriteLine("{0} {1} {2}", ByteArraysEqual(szarr, rainbow), szarr.Length, rainbow.Length);
Run Code Online (Sandbox Code Playgroud)

产量

错512 256

Mar*_*ell 7

如果你有一个任意的byte [],那么把它作为字符串的方法就是将它转换为hex或base-64之类的东西.最简单的:

byte[] key = ...
string s = Convert.ToBase64String(key);
Run Code Online (Sandbox Code Playgroud)

反之亦然:

key = Convert.FromBase64String();
Run Code Online (Sandbox Code Playgroud)

它是诱人的使用像System.Text.Encoding,但那是完全不正确的,不能被用来制造一个强大的转换.如果使用编码,则存在两个问题:

  • 许多钥匙无法成功往返
  • 许多不同的byte []键可以成为相同的字符串键

这两个都很糟糕!问题是使用是倒退的:编码将任意字符串转换为结构化字节[],从而允许对任何字符串进行编码/解码.Base-64将任意byte []转换为结构化字符串.非常微妙的区别,但非常重要.


McG*_*gle 3

您必须使用某种编码将字节转换为字符串。编码iso-8859-1将给出正确的结果:

var sz = Encoding.GetEncoding("iso-8859-1").GetString(rainbow);
var szarr = Encoding.GetEncoding("iso-8859-1").GetBytes(sz);
Console.WriteLine("{0} {1} {2}", ByteArraysEqual(szarr, rainbow), szarr.Length, rainbow.Length);
Run Code Online (Sandbox Code Playgroud)

真实 256 256

问题是 UTF8 每个字符需要多个字节。它可以用一个字节对前 128 个字符进行编码:

Console.Write(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(new byte[] { 127 })).Length);
Run Code Online (Sandbox Code Playgroud)

1

但其余的需要三个字节:

Console.Write(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(new byte[] { 128 })).Length);
Run Code Online (Sandbox Code Playgroud)

3

因此,当您将字节 0-255 转换为字符串并使用 UTF8 返回时,前 128 个作为一个字节返回,但最后 128 个作为 3. 128 + 3*128 = 512 返回,因此是您的结果。

ASCII 不知道如何处理超过 128 的字节,因此它们只是被编码为?,并且也以一个字节的形式返回。

  • Encoding.DefaultEncoding 不存在;Encoding.Default 指的是操作系统默认代码页,可以是很多不同的东西 - 它不是 8859-1 (2认同)