1 回答

TA貢獻1735條經驗 獲得超5個贊
在原始編碼字節(jié)中,有問題的字符代碼是0x0093。
您遇到的問題是,在Default系統上的編碼中(在 Windows 上將是系統當前的代碼頁),編碼的字符0x0093無法識別。因此,當您嘗試對其進行解碼時,您將獲得 UTF16 字符點0xfffd(這是 .NET 解碼器針對無法識別的字符的默認值)。然后將其編碼回默認編碼0x93c2(您在輸出中看到的字節(jié)序列,以十進制表示,194后跟147)。
無論如何,此行為與默認編碼設置為 UTF8 一致,可能表明它是 Linux 系統(大多數 Windows 系統將使用某些特定于區(qū)域設置的代碼頁作為默認編碼,而不是 UTF8)。
如果您希望將原始字節(jié)0x93轉換為具有基本相同值(即0x0093,又名'\u0093')的 UTF16 字符,那么您需要使用文本編碼來解碼原始字節(jié),其中代碼點0x93實際上轉換為 UTF16 代碼點0x0093。
幸運的是,有一個網站實際上會告訴我們哪些編碼包含該字符,以及它們的值是什么:https ://www.compart.com/en/unicode/charsets/containing/U+0093
從該表中,我們可以看到大量的編碼都是這種情況(還有一些編碼將 UTF16 字符'\u0093'編碼為不同的值,即0x33……顯然,我們不想要其中任何一個)。列表中的第一個編碼 - “ISO-8859-1” - 看起來合適,所以讓我們嘗試使用它來解碼你的字節(jié):
byte[] bytes = new byte[] { 0x19, 0x93, 0x0d, 0x0a, 0x1a, 0x0a };
string s = "\u0019\u0093\r\n\u001a\n";
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
System.Console.WriteLine(encoding.GetString(bytes) == s);
System.Console.WriteLine(s.Length);
foreach (var b in encoding.GetBytes(s))
{
System.Console.WriteLine("Byte: " + b);
}
System.Console.WriteLine(encoding.GetString(bytes) == s);
這輸出正是你想要的:
True
6
Byte: 25
Byte: 147
Byte: 13
Byte: 10
Byte: 26
Byte: 10
True
顯示的字節(jié)甚至是bytes數組中的確切字節(jié),我們可以通過將此行添加到程序末尾來演示:
System.Console.WriteLine(encoding.GetBytes(s).SequenceEqual(bytes));
這也將打印True.
這個故事的寓意是:了解您嘗試解碼的字節(jié)的原始編碼不是可選的。您必須確切地知道使用了哪種編碼,因為它就是:一種編碼。如果您使用了錯誤的編碼,您可能還想嘗試解碼加密的數據。
根據定義,不同的文本編碼是不同的。這意味著一種編碼中的字節(jié)含義與其他編碼中的字節(jié)含義完全不同(某種程度上……大多數編碼在最低 128 個代碼點中重疊,因為它們都基于 ASCII)。如果您使用錯誤的編碼來解碼某些字節(jié),您只會得到隨機結果(或者,在這種情況下,解碼器將根本無法識別該字符并將其轉換為表示無法識別的字符的占位符)。
- 1 回答
- 0 關注
- 168 瀏覽
添加回答
舉報