gpt4 book ai didi

字符串到字节 [] 转换的 .NET 缺陷?

转载 作者:行者123 更新时间:2023-12-01 09:36:52 29 4
gpt4 key购买 nike

我在从 SQL Server (2008R2) 数据库中的 NVARCHAR 字段检索加密数据时遇到了问题,对于某些记录,我的 C# .NET 应用程序中数据的字符串值与数据库记录中的数据字符串值不同。这有点难以证明,但我最终发现通过查看字符串的 byte[] 表示确实存在差异。

进一步玩弄我能够生成这个让我有点担心的测试应用程序。我拿了一个字节数组(为了简化设置从十六进制转换),用 Unicode 编码器将其转换为字符串,然后再转换回字节数组,发现生成的字节数组与原始字节数组不同!在下面的代码中,第一个十六进制字符串失败而第二个有效。

我的方法在这里有什么问题(我的意思不是尝试将字节数组转换为字符串)还是 .NET 框架中可能有问题?

using System;

namespace ByteArrayTest
{
class Program
{
static void Main(string[] args)
{
Console.WindowWidth = 80;
Console.Clear();

foreach (string s in new string[]
{
"00CD6C8300C2A2C09B9E6B1F258F7B1101000000AB4CB23EBE32F0DD",
"00CD6C8300C2A2C09B9E6B1F258F7B1101000000E12617F83C3F7F6A"
}
)
{
byte[] b1 = System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary.Parse(s).Value;
string tmp = System.Text.Encoding.Unicode.GetString(b1);

byte[] b2 = System.Text.Encoding.Unicode.GetBytes(tmp);

Console.WriteLine("Orig: {0}", s);

string s2 = BitConverter.ToString(b2).Replace("-", "");
Console.WriteLine("Conv: {0}", s2);

Console.WriteLine(s == s2 ? "EQUAL :-)" : "** NOT EQUAL **");
Console.WriteLine();
}

Console.WriteLine("Press ENTER to exit...");
Console.ReadLine();
}
}
}

我正在使用 VS2010 并在 .NET 框架 4 和 3.5 下对此进行了测试,结果如下:
Orig: 00CD6C8300C2A2C09B9E6B1F258F7B1101000000AB4CB23EBE32F0DD
Conv: 00CD6C8300C2A2C09B9E6B1F258F7B1101000000AB4CB23EBE32FDFF
** NOT EQUAL **

Orig: 00CD6C8300C2A2C09B9E6B1F258F7B1101000000E12617F83C3F7F6A
Conv: 00CD6C8300C2A2C09B9E6B1F258F7B1101000000E12617F83C3F7F6A
EQUAL :-)

问候,

最佳答案

如果您尝试在 NVARCHAR 字段中存储并非真正文本的任意不透明二进制数据,则应使用 base64 编码对其进行编码。试图仅将其视为 UTF-16 中的文本编码(这就是您在这里所做的)从根本上来说是个坏主意,并且很可能会丢失数据。作为可能发生这种情况的一个示例,您可能会得到一个包含 surrogate pair 一半的字符串。没有另一半。

我假设您的“加密数据”是通过调用 Encoding.Unicode.GetString(bytes) 存储的哪里bytes是加密数据吗?如果是这样,那绝对不是要走的路。用:

string text = Convert.ToBase64String(bytes);

相反,在检索数据时,使用
byte[] bytes = Convert.FromBase64String(text);

或者,首先使用专为二进制数据设计的数据库字段。

编辑:(从我的评论中复制)您给出的示例最终失败,将 U+DDF0 转换为 U+FFFD。这实际上正是我上面提到的场景——U+DDF0 是一个“低代理”,但它没有相应的“高代理”,因此 Encoding.GetString 将该字符转换为 U+FFFD,即“替换”字符”,这是(来自 Unicode chart )

used to replace an incoming character whose value is unknown or unrepresentable in Unicode



IIRC,你可以指定什么 Encoding当它遇到错误的二进制数据(这实际上是你给它的)并可能使它抛出异常时会这样做。

关于字符串到字节 [] 转换的 .NET 缺陷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6054502/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com