当我生成一个随机的字节序列,把这个序列解码成一个字符串表示,然后再把它编码回一个字节数组,它与原来编码的序列不同.请参见下面的示例:

[byte[]]$key = [byte[]]::new(32)
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($key)
$key

输出: 15个 一百七十三 一百九十八 八十九 一百六十二 161 144 104 125 86 一百五十四 204 166 二百三十八 一百九十三 40岁 51 58 一百六十七 0 一百五十 一百一十八 37 203 一百九十八 161 64 229 101 25个 一百七十六 201

$decoded = [System.Text.Encoding]::UTF8.GetString($key)
$encoded = [System.Text.Encoding]::UTF8.GetBytes($decoded)
$encoded

输出: 15个 二百三十九 一百九十一 189 二百三十九 一百九十一 189 八十九 二百三十九 一百九十一 189 二百三十九 一百九十一 189 二百三十九 一百九十一 189 104 125 86 二百三十九 一百九十一 189 204 166 二百三十九 一百九十一 189 二百三十九 一百九十一 189 40岁 51 58 二百三十九 一百九十一 189 0 二百三十九 一百九十一 189 一百一十八 37 二百三十九 一百九十一 189 一百九十八 161 64 二百三十九 一百九十一 189 101 25个 二百三十九 一百九十一 189 二百三十九 一百九十一 189

在解码/编码之后,字节序列被明显地修改.如果我使用[System.Text.Encoding]::Unicode...,则此过程运行良好.UTF8似乎不能处理某些字节,但我的印象是UTF8应该能够处理Unicode标准中的任何字符.谁能解释一下为什么会发生这种情况?请和谢谢

推荐答案

我几乎不是编码方面的专家,但这里有几个注意事项:

  1. 来自Encoding.UTF8个文档:

    此属性返回一个UTF8Ending对象,该对象将Unicode(UTF-16编码)字符编码 for each 字符一到四个字节的序列,并将UTF-8编码的字节数组解码为Unicode(UTF-16编码)字符.

  2. 并非每个可能的单个字节都表示UTF-8编码中的单个有效字符.UTF-8是一种可变宽度字符编码标准,它使用1到4个8位字节来表示所有有效的Unicode代码点.如果你查看encoding explanation的维基文章,你会发现单个字节只处理128个代码点(0-127),所以下面的内容已经" destruct "了编码-解码:

    var s = Encoding.UTF8.GetString(new byte[] { 128 });
    var bytes1 = Encoding.UTF8.GetBytes(s); // [239, 191, 189]
    
  3. 就我个人而言,我会try 使用Convert.ToBase64String()/Convert.FromBase64String()(或Convert.ToHexString()/Convert.FromHexString(),如果可用)对进行编码-解码.

.net相关问答推荐

.NET模拟具有泛型返回类型的方法

.NET Core 中的微服务

Dotnet 反射:使用 F# 中的out参数调用 MethodInfo 上的调用

cmd 冻结中的 dotnet 命令.怎么了?

如果只有一个 : 存在于字符串中,则提取冒号后的内容

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

.NET 中的线程安全集合

比较 C# 中的双精度值

为什么 .NET 内部 Hashtable 中有一个 Thread.Sleep(1)?

我可以从我的应用程序中抛出哪些内置 .NET 异常?

如何获取 Sql Server 数据库中所有模式的列表

在 Moq 中模拟泛型方法而不指定 T

如何在 C# 中打开 Excel 文件?

日期时间是什么意思?在 C# 中是什么意思?

在 C# 中与块等效?

如何在可取消的异步/等待中处理 TransactionScope?

如何使用 c# 仅获取目录中的文件名?

如何将 XPath 与 XElement 或 LINQ 一起使用?

序列化和反序列化 .NET 对象的最快方法

如何在 ASP.NET MVC 中重定向到动态登录 URL