回答
雖然@DPenner給出的響應是優異的(和我用它作爲起點),我想給出一些其他細節。 除了孤兒代理人,我認爲這是一個無效字符串的明確標誌,總是有一種可能性,即一個字符串包含未分配的代碼點,這種情況不能被視爲錯誤的。因爲新字符總是添加到Unicode標準中,請參閱Unicode http://en.wikipedia.org/wiki/Unicode#Versions的版本。而且,爲了使事情更清楚,當使用.NET 2.0時,此呼叫Char.GetUnicodeCategory(Char.ConvertFromUtf32(0x1F01C), 0);
返回UnicodeCategory.OtherNotAssigned
,但在使用.NET 4.0時它將返回UnicodeCategory.OtherSymbol
。
除此之外,還有一個有趣的地方:即使.NET類庫方法不同意如何處理Unicode非字符和不成對的替代字符。例如:
- 不成對代理char
System.Text.Encoding.Unicode.GetBytes("\uDDDD");
- 返回{ 0xfd, 0xff}
編碼爲Replacement character,即,數據被認爲是無效的。"\uDDDD".Normalize();
- 拋出異常並顯示消息「在索引0處找到無效的Unicode代碼點」,即數據被視爲無效。
- 非字符碼點
System.Text.Encoding.Unicode.GetBytes("\uFFFF");
- 返回{0xff, 0xff}
,也就是說,該數據被視爲有效。"\uFFFF".Normalize();
- 拋出異常並顯示消息「在索引0處找到無效的Unicode代碼點」,即數據被視爲無效。
下面是將一個字符串爲無效字符搜索的方法:
/// <summary>
/// Searches invalid charachters (non-chars defined in Unicode standard and invalid surrogate pairs) in a string
/// </summary>
/// <param name="aString"> the string to search for invalid chars </param>
/// <returns>the index of the first bad char or -1 if no bad char is found</returns>
static int FindInvalidCharIndex(string aString)
{
int ch;
int chlow;
for (int i = 0; i < aString.Length; i++)
{
ch = aString[i];
if (ch < 0xD800) // char is up to first high surrogate
{
continue;
}
if (ch >= 0xD800 && ch <= 0xDBFF)
{
// found high surrogate -> check surrogate pair
i++;
if (i == aString.Length)
{
// last char is high surrogate, so it is missing its pair
return i - 1;
}
chlow = aString[i];
if (!(chlow >= 0xDC00 && chlow <= 0xDFFF))
{
// did not found a low surrogate after the high surrogate
return i - 1;
}
// convert to UTF32 - like in Char.ConvertToUtf32(highSurrogate, lowSurrogate)
ch = (ch - 0xD800) * 0x400 + (chlow - 0xDC00) + 0x10000;
if (ch > 0x10FFFF)
{
// invalid Unicode code point - maximum excedeed
return i;
}
if ((ch & 0xFFFE) == 0xFFFE)
{
// other non-char found
return i;
}
// found a good surrogate pair
continue;
}
if (ch >= 0xDC00 && ch <= 0xDFFF)
{
// unexpected low surrogate
return i;
}
if (ch >= 0xFDD0 && ch <= 0xFDEF)
{
// non-chars are considered invalid by System.Text.Encoding.GetBytes() and String.Normalize()
return i;
}
if ((ch & 0xFFFE) == 0xFFFE)
{
// other non-char found
return i;
}
}
return -1;
}
這很有趣,雖然據我所知,行爲實際上符合Unicode標準。由於'GetBytes()'是一種轉換方法,當存在非法字節序列時,它是[required](http://www.unicode.org/faq/utf_bom.html#gen8)以某種方式發出錯誤信號。對於''\ uDDDD'.Normalize()',該字符串首先是無效的,因此Unicode對此沒有任何可說的。用'「\ uFFFF」.Normalize()',[TR 15的第12節](http://www.unicode.org/reports/tr15/#Stabilized_Strings)明確允許進程在具有未分配字符的字符串上中止。 – DPenner1 2014-11-28 04:15:14
你對代孕對不公平,是的。你使用'System.Text.Encoding.Unicode',但這只是一個方便的方法來獲得一個新的System.Text.UnicodeEncoding(bigEndian:false,byteOrderMark:true,throwOnInvalidBytes:false) 。如果使用'new System.Text.UnicodeEncoding(bigEndian:false,byteOrderMark:true,throwOnInvalidBytes:true)',那麼您會在不成對的代理案例中遇到異常。 – 2015-01-26 19:21:18
嗯,我認爲.NET字符串內的無效代碼點只有在某人將某個元素設置爲hi或lo-surrogate時纔會發生。也可能發生某人從有效代理對中刪除hi或lo-surrogate的情況,後者不僅可以通過刪除元素而發生,還可以通過更改元素的值來實現。在我看來,答案是「是」,它可能發生,唯一的原因可能是在字符串中存在孤兒hi-or lo-surrogate。你有一個真正的例子字符串?張貼在這裏,我可以檢查什麼是錯的。
B.t.w.對於UTF-16文件也是如此。這有可能發生。對於帶有0xFFEE BOM的utf-16LE文件,請確保您的第一個字符不是0,因爲那麼您的前4個字節是0xFFFE0000,肯定會被解釋爲utf-32LE BOM而不是utf-16LE BOM!
不,我沒有樣品,但如果可能的話,我希望看到一個樣品。 – 2014-11-21 17:14:48
我有這樣的文件,但我怎麼上傳它?我留下了一個鏈接到我的http服務器,顯示了一部分文件的截圖:[鏈接到腐敗的utf-16文件](http://peter.brightman.de/pics/OrphanedSurrogate.jpg) – brighty 2014-11-23 13:45:25
在.NET和C#中的所有字符串都使用UTF-16編碼,但有一個例外(從Jon Skeet's blog拍攝):
...有兩種不同的表示:大部分的時間,UTF- 16 被使用,但屬性構造參數使用UTF-8 ...
是的,這是可能的。根據Microsoft的文檔,.NET String簡單地說就是
String對象是表示字符串的System.Char對象的順序集合。
而.NET Char
表示一個字符作爲UTF-16代碼單元。
總之,這意味着.NET字符串只是一系列UTF-16代碼單元,無論它們是否是根據Unicode標準的有效字符串。有很多方法可以發生,我可以想到的一些更常見的方法是:
- 非UTF-16字節流被錯誤地放入String對象而沒有正確轉換。
- 一個String對象被分割在一個代理對之間。
- 有人故意包含這樣一個字符串來測試系統的健壯性。
其結果,下面的C#代碼是完全合法的,並且將編譯:
class Test
static void Main(){
string s =
"\uEEEE" + // A private use character
"\uDDDD" + // An unpaired surrogate character
"\uFFFF" + // A Unicode noncharacter
"\u0888"; // A currently unassigned character
System.Console.WriteLine(s); // Output is highly console dependent
}
}
- 1. 字符串到Unicode和Unicode到十進制代碼點(C++)
- 2. Unicode代碼字符串
- 3. 的Python:解碼同時包含Unicode代碼點的字符串和Unicode文本
- 4. Unicode代碼點和java字符
- 5. 斯威夫特:在使用「無效的Unicode標」的錯誤Unicode代碼點作爲字符串字面
- 6. 如何將Unicode代碼點轉換爲Unicode字符串?
- 7. java字符串unicode代碼點轉換爲字符
- 8. 如何迭代Java字符串的unicode代碼點?
- 9. 有效的Unicode字符串
- 10. MySQL的錯誤代碼:1300 UTF8無效的字符串:「」與「\ \」 UTF8 Unicode中的前「Unicode字符的盈
- 11. C獲取字符的Unicode代碼點
- 12. 如何從字符串中刪除無效的代碼點?
- 13. 可能從無效的代碼點構造java字符串?
- 14. 將.net字符串對象轉換爲base64編碼字符串
- 15. 有效的nodejs代碼字符串到JavaScript對象
- 16. Ruby 1.9,Rails 3和Unicode:代碼將無法識別Unicode字符
- 17. 字符串化內聯::的Python:對象編碼的Unicode字符串
- 18. python中的unicode字符串的補充代碼點
- 19. 從Unicode代碼點獲取字符 - C++
- 20. 轉換任何字符串或在PHP中的Unicode代碼點
- 21. 字符串轉換爲它的Unicode代碼點
- 22. 蟒紋Unicode字符串,而不是代碼點
- 23. Python:將Unicode代碼點文件名轉換爲字符串
- 24. Java顯示unicode代碼點而不是字符串literal
- 25. 驗證Unicode字符串和轉義如果Unicode是無效的(C/C++)
- 26. 比較中文unicode字符串,當多個代碼點是相同的字符?
- 27. 如何在Swift中獲得字符/字符串的unicode代碼點表示?
- 28. Python unicode字符代碼?
- 29. .NET Webservice =代理對無效
- 30. 從unicode字符串去除特殊字符和標點符號
壞PInvoke的,通常。避免詢問XY問題。 – 2014-11-20 21:10:44
@HansPassant我只能發佈我的第一個問題。對於太短的問題有一些驗證,所以我還添加了第二部分,我認爲這是相關的。 – 2014-11-20 21:14:09
@HansPassant:那麼,沒有無與倫比的代理人不會錯誤的方式?未分配的碼點呢? – Deduplicator 2014-11-20 21:24:49