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

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

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


当前回答

可以使用以下代码将字符串转换为.NET中的字节数组

string s_unicode = "abcéabc";
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(s_unicode);

其他回答

代码如下:

// Input string.
const string input = "Dot Net Perls";

// Invoke GetBytes method.
// ... You can store this array as a field!
byte[] array = Encoding.ASCII.GetBytes(input);

// Loop through contents of the array.
foreach (byte element in array)
{
    Console.WriteLine("{0} = {1}", element, (char)element);
}

C#将字符串转换为字节数组:

public static byte[] StrToByteArray(string str)
{
   System.Text.UTF8Encoding  encoding=new System.Text.UTF8Encoding();
   return encoding.GetBytes(str);
}

只需使用此选项:

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

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

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

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

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

当被问及您打算如何处理字节时,您回答:

我将对它进行加密。我可以在不进行转换的情况下对其进行加密,但我仍然想知道为什么编码会在这里发挥作用。给我字节就是我说的。

无论您是否打算通过网络发送加密数据,稍后将其加载回内存,或将其流式传输到另一个进程,您显然都打算在某个时刻对其进行解密。在这种情况下,答案是您正在定义通信协议。通信协议不应根据编程语言及其相关运行时的实现细节来定义。这有几个原因:

您可能需要与以不同语言或运行时实现的流程进行通信。(例如,这可能包括在另一台机器上运行的服务器或将字符串发送到JavaScript浏览器客户端。)该程序将来可以用不同的语言或运行时重新实现。.NET实现可能会更改字符串的内部表示形式。您可能会觉得这听起来有些牵强,但这实际上发生在Java9中,以减少内存使用。.NET没有理由不能效仿。Skeet表明,UTF-16在今天可能不是最佳的,因为表情符号和其他Unicode块也需要2个以上的字节来表示,这增加了内部表示在未来可能发生变化的可能性。

为了进行通信(无论是与完全不同的进程还是将来与相同的程序),您需要严格定义协议,以最大限度地减少使用协议或意外创建错误的难度。依赖于.NET的内部表示并不是一个严格的、明确的,甚至不能保证是一致的定义。标准编码是一个严格的定义,将来不会让您失望。

换句话说,如果不指定编码,就无法满足一致性要求。

如果您发现由于.NET在内部使用了UTF-16或出于其他原因,您的进程的性能明显更好,那么您当然可以选择直接使用UTF-16,但您需要显式选择编码,并在代码中显式执行这些转换,而不是依赖于.NET的内部实现。

因此,选择一种编码并使用它:

using System.Text;

// ...

Encoding.Unicode.GetBytes("abc"); # UTF-16 little endian
Encoding.UTF8.GetBytes("abc")

正如您所看到的,与实现您自己的读写器方法相比,仅使用内置的编码对象实际上也是更少的代码。