我可以在字节和字符串之间混合UTF-16转换和UTF-8转换吗?

本文关键字:转换 UTF-8 UTF-16 之间 字节 字符串 我可以 混合 | 更新日期: 2023-09-27 17:51:04

短版

这是恒等函数吗?

f = (gₐ · hᵤ · gᵤ · hₐ)

地点:

  • hₐ是从字节到字符串的UTF-16转换,
  • gₐ是从字符串到字节的UTF-16转换,
  • gᵤEncoding.UTF8.GetBytes()
  • hᵤEncoding.UTF8.GetString()

长版本

我使用WebSocket4Net在c#应用程序和c#服务之间通过WebSockets发送和接收消息。

一些消息是二进制的,我应该在与库交互时将它们从二进制转换为字符串,因为当它的Send()方法允许发送字节数组时,它的MessageReceived只将接收到的消息作为字符串进行通信。

为了将字节转换为字符串和字符串转换为字节,我遵循Mehrdad的答案,其中使用。net框架的内部编码,即UTF-16。

另一方面,根据代码源(参见例如DraftHybi10Processor.cs,第114行),WebSocket4Net使用UTF-8将字符串转换为字节,并将字节转换为字符串。

会引起问题吗?数据可能丢失吗?

我可以在字节和字符串之间混合UTF-16转换和UTF-8转换吗?

如果您需要将二进制数据作为字符串发送,那么,这就是Base-64和类似编码的用途。如果你需要发送一个字符串作为字符串…把它作为字符串发送。如果您需要以字节形式发送字符串,Unicode (UTF-16)或UTF-8就可以了。字符串不是简单的字节数组(即使它们可以在必要时以这种方式表示)。Unicode是一种非常复杂的编码(参见http://www.joelonsoftware.com/articles/Unicode.html;阅读它——这是必须的)。您知道可以获得将单个字符分成5个字节的unicode规范化吗?同样的字符也可以解释为2。或者是一个完全不同的数。我没有观察到它,但我希望一些字节数组在UTF-16(这是当前。net中默认的字符串编码)中完全无效。

我不打算证明你的"双重编码"是有缺陷的。我不确定,也许能行。然而,你将得到的字符串将是相当愚蠢的,你会有很多麻烦来编码它,以确保你不是在发送命令或其他东西。

更重要的是——你没有表现出意图。你在做微优化,牺牲可读性。更糟糕的是,您依赖于实现细节,这些细节对于。net的后续版本来说不一定是可移植的或稳定的,更不用说其他环境了。

除非你有一个非常非常好的理由(基于实际的性能分析,而不是"直觉"),否则请使用简单、可读的解决方案。如果有必要,你总是可以提高的。

EDIT:一个示例代码,说明为什么使用Unicode编码非Unicode字节是一个坏主意:

Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(new byte[] { 200, 8 }))

输入的两个字节变成了四个字节,{ 239, 191, 189, 8 }。不完全是你想要的