C#big-endian UCS-2

时间:2011-08-07 08:23:12

标签: c# .net endianness

我目前正在开发的项目需要与我们没有制作的客户端系统进行交互,因此我们无法控制数据的发送方式。问题是在C#中工作,它似乎对UCS-2没有任何支持,对big-endian的支持也很少。 (据我所知)

我想知道的是,如果我在.net中查看过任何内容,或者其他人已经制作并发布了我们可以使用的内容。如果不是,我将采用自定义方法对其进行编码/解码,如果可能的话。

但是谢谢你的时间。

编辑: BigEndianUnicode 工作正确解码字符串,问题是接收其他数据为大端,到目前为止使用IPAddress.HostToNetworkOrder()按照其他地方的建议允许我解码一半的字符串(Merli?是什么出现,它应该是Merlin33069)

我正在梳理短代码以查看我错过了另一个长度变量

解决方案: 在确定bigendian变量是主要问题之后,我回过头来查看详细信息,似乎字符串的长度是以字符计数发送的,而不是字节计数(在utf中,似乎char是两个字节)所有我需要做的就是加倍,然后就解决了。谢谢大家的帮助。

3 个答案:

答案 0 :(得分:2)

编辑:现在我们知道问题不在于文本数据的编码,而在于长度的编码。有几个选择:

  • 反转字节,然后使用内置的BitConverter代码(我假设您正在使用的代码;那个或BinaryReader
  • 使用重复的“添加和转移”操作自行执行转换
  • 使用MiscUtil中的EndianBitConverterEndianBinaryReader类,类似于BitConverterBinaryReader,但您可以指定字节顺序。

您可能正在寻找Encoding.BigEndianUnicode。这是大端UTF-16编码,严格来说与UCS-2不一样(正如Marc所指出的那样),但除非你给它包括BMP以外的字符(即U + FFFF以上),否则应该没问题。 ,无法在UCS-2中表示,但 以UTF-16表示。

来自Wikipedia page

  

较旧的UCS-2(2字节通用字符集)是一种类似的字符编码,在1996年7月的Unicode标准2.0版本中被UTF-16取代。2它产生一个固定长度通过简单地使用代码点作为16位代码单元来格式化,并且对于0-0xFFFF范围内的所有代码点的96.9%产生与UTF-16完全相同的结果,包括已在其中分配了值的所有字符时间。

我发现客户端系统不太可能向您发送存在差异的字符(基本上是代理对,无论如何都永久保留用于此用途)。

答案 1 :(得分:2)

string x = "abc";
byte[] data = Encoding.BigEndianUnicode.GetBytes(x);

在另一个方向:

string decodedX = Encoding.BigEndianUnicode.GetString(data);

它不是完全 UCS-2,但对大多数情况来说已经足够了。

UPD: Unicode FAQ

  

问:UCS-2和UTF-16有什么区别?

     

答:UCS-2是过时的术语,指的是Unicode   在代理代码点和之前执行到Unicode 1.1   UTF-16被添加到该标准的2.0版本中。这个词现在应该   要避免。

     

UCS-2没有定义不同的数据格式,因为UTF-16和UCS-2   对于数据交换而言是相同的。两者都是16位,并且有   完全相同的代码单元表示。

     

有时在过去,一个实现被标记为“UCS-2”   表示它不支持补充字符,也不支持   将代理代码点对解释为字符。这样的   实现不会处理字符属性的处理,   补充字符的代码点边界,整理等。

答案 2 :(得分:1)

UCS-2非常接近UTF-16,Encoding.BigEndianUnicode 几乎总是就足够了。

关于读取长度前缀(作为big-endian)的问题(注释)可以通过移位操作更正确地解决,这将在所有系统上做正确的事情。例如:

Read4BytesIntoBuffer(buffer);
int len =(buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]); 

这将在任何系统上运行相同的(在解析大端4字节int时),无论本地字节顺序如何。