Node.js 和 .NET 中的 UTF-8 编码差异

UTF-8 encoding difference in Node.js and .NET

提问人:zolipapa 提问时间:7/28/2023 最后编辑:Peter Mortensenzolipapa 更新时间:8/6/2023 访问量:119

问:

我有一个字节数组,我想获得一个使用 UTF-8 编码的字符串,但我在 Node.js 和 .NET 中得到不同的结果。

节点 .js:

// Node.js
const b7 = Buffer.from([65, 119, 212, 250, 152, 244, 166 ]).toString();
b7.length === 7; // true
b7 === 'Aw�����' // true

。网:

// C# .NET
byte[] b6 = new byte[7] { 65, 119, 212, 250, 152, 244, 166 };
UTF8Encoding encoding = new UTF8Encoding();
string s6 = encoding.GetString(b6);
s6.length == 6; // true
s6 == "Aw����"; // true
  1. 如何在 Node.js 中获得与 .NET 相同的结果?
  2. 为什么 .NET 版本较短?

其他被证明很重要的信息是 .NET 目标。上面的 .NET 代码是使用 .NET Framework 4.6.1 的 Web 应用程序的一部分。

JavaScript C# 节点.js .NET UTF-8

评论

0赞 Sweeper 7/28/2023
在 C# 代码中,哪种编码是 ?encoding
2赞 Sweeper 7/28/2023
Encoding.UTF8.GetString(b6);按预期生成 7 个字符。
0赞 zolipapa 7/28/2023
@Sweeper 对不起,我忘了添加该部分。 .NET 代码使用System.Text.UTF8Encoding
0赞 zolipapa 7/28/2023
@Sweeper 从您的评论中,我意识到我使用的 .Net 版本也很重要,因为我为 .Net Framework 4.6.1 获取了 6 个字符,但是如果我创建一个以 .NET 6 为目标的控制台应用程序,它将产生 7 个字符。我也不明白为什么......

答:

2赞 CodeconValley 7/28/2023 #1

字节数组中的字符串在 Node.js 和 .NET 中具有不同长度和内容的原因是它们以不同的方式处理无效或不可解码的 UTF-8 序列。

使用 Buffer.from([...]) 时。toString() 在 Node.js 中,它不会抛出错误或替换无效序列。相反,它将每个无效字节显示为字符串中的“替换字符”( )。

另一方面,当您在 .NET 中使用 UTF8Encoding.GetString(byte[]) 时,它会将无效字节替换为字符串中的 Unicode“替换字符”(U+FFFD)。但是,此 Unicode 字符不计入字符串长度,因此 .NET 中的字符串较短。

如果要在 Node.js 和 .NET 之间具有相同的行为,可以指定在将无效字节转换为字符串时如何处理它们。

在 Node.js 中,可以使用 Buffer.from([...])。toString('utf-8') 并传递 'utf-8' 作为编码参数,以遵循 UTF-8 标准处理无效序列。

在 .NET 中,可以使用 Encoding.UTF8.GetString(byte[], int, int) 并将 EncoderFallback 参数设置为 EncoderFallback.ReplacementFallback,以匹配用于处理无效序列的 Node.js 行为。

下面介绍如何修改代码以实现一致的行为:

节点 .js:

const b7 = Buffer.from([65, 119, 212, 250, 152, 244, 166]).toString('utf-8');
console.log(b7.length); // 6
console.log(b7); // "Aw����"

。网:

byte[] bb6 = new byte[7] { 65, 119, 212, 250, 152, 244, 166 };
UTF8Encoding encoding = new UTF8Encoding();
string s6 = encoding.GetString(bb6, 0, bb6.Length);
Console.WriteLine(s6.Length); // 6
Console.WriteLine(s6); // "Aw����"

通过显式指定无效序列的编码和处理,可以确保 Node.js 和 .NET 之间的 UTF-8 解码行为一致。

评论

0赞 zolipapa 7/31/2023
我检查了 Node.js 代码,但对我来说它返回 b7.length === 7。你 100% 确定你尝试了那段代码吗?
1赞 NotTheDr01ds 8/5/2023
欢迎来到 Stack Overflow,CodeconValley!到目前为止,你的一些答案似乎可能完全或部分由人工智能(例如,ChatGPT)编写。请注意,这里不允许发布 AI 生成的内容。如果您使用 AI 工具来协助回答任何问题,我鼓励您将其删除。我们希望您能坚持下去,并通过发布您自己的优质内容继续成为我们社区的重要组成部分。谢谢!
2赞 NotTheDr01ds 8/5/2023
读者应该仔细和批判性地审查这个答案,因为人工智能生成的信息通常包含根本性的错误和错误信息。如果您发现质量问题和/或有理由相信此答案是由 AI 生成的,请留下相应的反馈。