我目前正在开发的项目需要与我们没有制作的客户端系统进行交互,因此我们无法控制数据的发送方式。问题是在C#中工作,它似乎对UCS-2没有任何支持,对big-endian的支持也很少。 (据我所知)
我想知道的是,如果我在.net中查看过任何内容,或者其他人已经制作并发布了我们可以使用的内容。如果不是,我将采用自定义方法对其进行编码/解码,如果可能的话。
但是谢谢你的时间。
编辑: BigEndianUnicode 工作正确解码字符串,问题是接收其他数据为大端,到目前为止使用IPAddress.HostToNetworkOrder()按照其他地方的建议允许我解码一半的字符串(Merli?是什么出现,它应该是Merlin33069)
我正在梳理短代码以查看我错过了另一个长度变量
解决方案: 在确定bigendian变量是主要问题之后,我回过头来查看详细信息,似乎字符串的长度是以字符计数发送的,而不是字节计数(在utf中,似乎char是两个字节)所有我需要做的就是加倍,然后就解决了。谢谢大家的帮助。
答案 0 :(得分:2)
编辑:现在我们知道问题不在于文本数据的编码,而在于长度的编码。有几个选择:
BitConverter
代码(我假设您正在使用的代码;那个或BinaryReader
)EndianBitConverter
或EndianBinaryReader
类,类似于BitConverter
和BinaryReader
,但您可以指定字节顺序。您可能正在寻找Encoding.BigEndianUnicode
。这是大端UTF-16编码,严格来说与UCS-2不一样(正如Marc所指出的那样),但除非你给它包括BMP以外的字符(即U + FFFF以上),否则应该没问题。 ,无法在UCS-2中表示,但 以UTF-16表示。
较旧的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时),无论本地字节顺序如何。