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

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

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


当前回答

bytes[] buffer = UnicodeEncoding.UTF8.GetBytes(string something); //for converting to UTF then get its bytes

bytes[] buffer = ASCIIEncoding.ASCII.GetBytes(string something); //for converting to ascii then get its bytes

其他回答

Use:

    string text = "string";
    byte[] array = System.Text.Encoding.UTF8.GetBytes(text);

结果是:

[0] = 115
[1] = 116
[2] = 114
[3] = 105
[4] = 110
[5] = 103

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

因为没有“字符串的字节”这样的东西。

字符串(或更一般的文本)由字符组成:字母、数字和其他符号。这就是全部。然而,计算机对字符一无所知;它们只能处理字节。因此,如果要使用计算机存储或传输文本,需要将字符转换为字节。你是怎么做到的?这里是编码出现的地方。

编码只是将逻辑字符转换为物理字节的惯例。最简单和最著名的编码是ASCII,如果你用英语写作,这就是你所需要的。对于其他语言,您将需要更完整的编码,因为Unicode是当今最安全的选择。

因此,简而言之,尝试“不使用编码获取字符串的字节”与“不使用任何语言编写文本”一样不可能。

顺便说一句,我强烈建议你(以及任何人)阅读这篇小智慧:绝对最低限度每个软件开发人员绝对、积极地必须了解Unicode和字符集(没有借口!)

随着C#7.2发布的Span<T>的出现,将字符串的底层内存表示捕获到托管字节数组中的规范技术是:

byte[] bytes = "rubbish_\u9999_string".AsSpan().AsBytes().ToArray();

将其转换回去应该是一件不容易的事,因为这意味着您实际上正在以某种方式解释数据,但为了完整性:

string s;
unsafe
{
    fixed (char* f = &bytes.AsSpan().NonPortableCast<byte, char>().DangerousGetPinnableReference())
    {
        s = new string(f);
    }
}

NonPortableCast和DangerousGetPinnableReference这两个名称应该进一步证明您可能不应该这样做。

注意,使用Span<T>需要安装System.Memory NuGet包。

无论如何,实际的原始问题和后续评论暗示底层内存没有被“解释”(我假设这意味着没有修改或读取,超出了按原样编写的需要),这表明应该使用Stream类的某些实现,而不是将数据作为字符串进行推理。

计算机只理解原始二进制数据,原始比特。一位是二进制数字:0或1。8位数字是一个字节。一个字节是介于0和255之间的数字。

ASCII是一种将数字转换为字符的表格。0到31之间的数字是控件:制表符、换行符和其他。32到126之间的数字为可打印字符:字母a,数字1,%符号,下划线_

因此,对于ASCII,有33个控制字符和95个可打印字符。

ASCII是当今最常用的字符编码。Unicode表的第一个条目是ASCII,并与ASCII字符集匹配。

ASCII是一个7位字符集。介于0和127之间的数字。使用8位,我们可以达到255位。

ASCII最常见的替代品是EBCDIC,它与ASCII不兼容,今天仍然存在于IBM计算机和数据库中。

1字节,因此8位数字是当今计算机科学中最常用的单位。1字节是介于0和255之间的数字。

ASCII为0到127之间的每个数字定义了一个含义。

与128和255之间的数字相关联的字符取决于所使用的字符编码。目前广泛使用的两种字符编码是windows1252和UTF-8。

在windows1252中,欧元符号对应的数字是128。1字节:[A0]。在Unicode数据库中,欧元符号是数字8364。

现在我给你电话8364。两个字节:[20,AC]。在UTF-8中,欧元符号是数字14844588。三个字节:[E282AC]。

现在我给你一些原始数据。假设20AC。是两个windows1252字符:£还是一个Unicode€符号?

我给你一些原始数据。e282交流。82是windows1252中未分配的字符,因此它可能不是windows1252。它可能是macRoman“”C“”或OEM 437“”或UTF-8“€”符号。

根据字符编码的特性和统计数据,可以猜测原始字节流的编码,但没有可靠的方法。128到255之间的数字在UTF-8中是无效的。é在某些语言(法语)中很常见,因此如果您看到许多字节的值E9被字母包围,那么它可能是一个windows1252编码字符串,E9字节表示é字符。

当您有一个表示字符串的原始字节流时,了解匹配的编码比猜测要好得多。

下面是曾经被广泛使用的各种编码中的一个原始字节的屏幕截图。

公认的答案非常非常复杂。为此,请使用包含的.NET类:

const string data = "A string with international characters: Norwegian: ÆØÅæøå, Chinese: 喂 谢谢";
var bytes = System.Text.Encoding.UTF8.GetBytes(data);
var decoded = System.Text.Encoding.UTF8.GetString(bytes);

如果你不需要。。。