如何在.NET(C#)中将字符串转换为字节[]而不手动指定特定编码?

我要加密字符串。我可以在不进行转换的情况下对其进行加密,但我仍然想知道为什么编码会在这里发挥作用。

此外,为什么还要考虑编码?我不能简单地获取字符串存储的字节数吗?为什么依赖字符编码?


当前回答

要将字符串转换为字节[],请使用以下解决方案:

string s = "abcdefghijklmnopqrstuvwxyz";
byte[] b = System.Text.UTF32Encoding.GetBytes(s);

我希望这有帮助。

其他回答

与这里的答案相反,如果不需要解释字节,则不需要担心编码!

正如您提到的,您的目标很简单,就是“获取字符串存储的字节数”。(当然,还要能够根据字节重新构造字符串。)

对于这些目标,我真的不明白为什么人们总是告诉你你需要编码。你当然不需要担心编码。

只需执行以下操作:

static byte[] GetBytes(string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

// Do NOT use on arbitrary bytes; only use on GetBytes's output on the SAME system
static string GetString(byte[] bytes)
{
    char[] chars = new char[bytes.Length / sizeof(char)];
    System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
    return new string(chars);
}

只要你的程序(或其他程序)不试图以某种方式解释字节,而你显然没有提到你打算这样做,那么这种方法就没有错!担心编码只会让你的生活变得更加复杂,没有真正的原因。

这种方法的额外好处:字符串是否包含无效字符无关紧要,因为您仍然可以获取数据并重建原始字符串!

它将以相同的方式进行编码和解码,因为您只是在查看字节。

但是,如果您使用特定的编码,则会给您带来编码/解码无效字符的麻烦。

由于以下事实,字符串可以通过几种不同的方式转换为字节数组:.NET支持Unicode,Unicode标准化了几种称为UTF的不同编码。它们具有不同长度的字节表示,但在这个意义上是等价的,即当字符串被编码时,它可以被编码回字符串,但如果字符串用一个UTF编码,并且在不同UTF的假设下解码,如果可能会出错。

此外,.NET支持非Unicode编码,但它们在一般情况下无效(只有在实际字符串(如ASCII)中使用有限的Unicode代码点子集时才有效)。在内部,.NET支持UTF-16,但对于流表示,通常使用UTF-8。它也是互联网的事实标准。

毫不奇怪,System.Text.Encoding类是一个抽象类,它支持将字符串序列化为字节数组和反序列化;它的派生类支持具体编码:ASCIIEncoding和四个UTF(System.Text.UnicodeEncoding支持UTF-16)

参考此链接。

对于使用System.Text.Encoding.GetBytes对字节数组进行序列化。对于反向操作,使用System.Text.Encoding.GGetChars。此函数返回字符数组,因此要获取字符串,请使用字符串构造函数System.string(char[])。请参阅本页。

例子:

string myString = //... some string

System.Text.Encoding encoding = System.Text.Encoding.UTF8; //or some other, but prefer some UTF is Unicode is used
byte[] bytes = encoding.GetBytes(myString);

//next lines are written in response to a follow-up questions:

myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);
myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);

//how many times shall I repeat it to show there is a round-trip? :-)

LINQ的简单代码

string s = "abc"
byte[] b = s.Select(e => (byte)e).ToArray();

编辑:如下所述,这不是一个好方法。

但您仍然可以使用它来理解LINQ,并使用更合适的编码:

string s = "abc"
byte[] b = s.Cast<byte>().ToArray();

字符既是字体表的查找键,也是词汇传统,如排序、大小写版本等。

因此,字符不是字节(8位),字节不是字符。特别是,一个字节的256个排列不能容纳某些书面语言中的数千个符号,更不用说所有语言了。因此,已经设计了各种编码字符的方法。某些编码用于特定类别的语言(ASCII编码);使用代码页的多种语言(扩展ASCII);或者,雄心勃勃地,通过根据需要选择性地包括额外的字节,Unicode来实现所有语言。

在系统(如.NET框架)中,字符串表示特定的字符编码。在.NET中,此编码为Unicode。由于框架默认读取和写入Unicode,因此在.NET中通常不需要处理字符编码。

然而,一般来说,要从字节流将字符串加载到系统中,您需要知道源编码,从而正确解释并随后翻译它(否则代码将被视为已在系统的默认编码中,从而呈现乱码)。类似地,当字符串被写入外部源时,它将以特定的编码被写入。

只需使用此选项:

byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);