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

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

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


当前回答

我不确定,但我认为字符串将其信息存储为一个Chars数组,这对字节来说效率很低。具体来说,Char的定义是“表示Unicode字符”。

以以下示例为例:

String str = "asdf éß";
String str2 = "asdf gh";
EncodingInfo[] info =  Encoding.GetEncodings();
foreach (EncodingInfo enc in info)
{
    System.Console.WriteLine(enc.Name + " - " 
      + enc.GetEncoding().GetByteCount(str)
      + enc.GetEncoding().GetByteCount(str2));
}

请注意,在这两种情况下,Unicode答案都是14个字节,而UTF-8答案第一种只有9个字节,第二种只有7个字节。

因此,如果您只想要字符串所使用的字节,只需使用Encoding.Unicode,但存储空间会很低。

其他回答

公认的答案非常非常复杂。为此,请使用包含的.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);

如果你不需要。。。

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

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

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

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

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

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

为了证明Mehrrad的声音回答有效,他的方法甚至可以持久化未配对的代理字符(其中许多人对我的答案持反对态度,但每个人都有同样的错误,例如System.Text.Encoding.UTF8.GetBytes、System.Text.Encding.Unicode.GetBytes;例如,这些编码方法不能持久化高代理字符d800,而这些方法只是用值fffd替换高代理字符):

using System;

class Program
{     
    static void Main(string[] args)
    {
        string t = "爱虫";            
        string s = "Test\ud800Test"; 

        byte[] dumpToBytes = GetBytes(s);
        string getItBack = GetString(dumpToBytes);

        foreach (char item in getItBack)
        {
            Console.WriteLine("{0} {1}", item, ((ushort)item).ToString("x"));
        }    
    }

    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;
    }

    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);
    }        
}

输出:

T 54
e 65
s 73
t 74
? d800
T 54
e 65
s 73
t 74

尝试使用System.Text.Encoding.UTF8.GetBytes或System.Text.Encding.Unicode.GetBytes,它们只会用值fffd替换高代理项字符

每当这个问题发生变化时,我仍然在想一个序列化程序(无论是来自Microsoft还是来自第三方组件),它可以持久化字符串,即使它包含不成对的代理字符;我时不时地在谷歌上搜索这个:序列化不成对的代理角色.NET。这不会让我失眠,但偶尔有人评论我的答案,说它有缺陷,但他们的答案在不成对的替代角色方面同样有缺陷,这让我很烦。

Darn,Microsoft应该在BinaryFormatter中使用System.Buffer.BlockCopyツ

谢谢!

byte[] strToByteArray(string str)
{
    System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    return enc.GetBytes(str);
}

对于串行通信项目,我必须将字符串转换为字节数组-我必须处理8位字符,而且我无法找到使用框架转换器的方法,这样既不会添加两个字节条目,也不会错误地转换具有第八位集的字节。所以我做了以下工作:

string message = "This is a message.";
byte[] bytes = new byte[message.Length];
for (int i = 0; i < message.Length; i++)
    bytes[i] = (byte)message[i];