2011-04-10 16 views
2

我檢查了AsciiEncoding的GetByteCount方法。它做了很長的計算而不是返回String.Length。它對我沒有任何意義。你有好主意嗎?爲什麼IsSingleByte Encoding的GetByteCount做了計算

+0

它*看起來像它試圖說明高/低代理對......這似乎奇怪的ASCII – 2011-04-10 07:54:57

+0

@Marc:會計對代理對不是太愚蠢國際海事組織,但它似乎並沒有工作。看我最近的編輯。 – 2011-04-10 08:04:20

回答

3

編輯:我只是試圖重現這一點,我目前不能強制一個ASCIIEncoding而是有一個不同的替代品。相反,我不得不使用Encoding.GetEncoding來獲得一個可變的。所以對於ASCIIEncoding,我同意......但對於IsSingleByte返回true的其他實現,您仍然有下面的潛在問題。


考慮試圖讓這只包含ASCII字符的字符串的字節數。編碼必須考慮到EncoderFallback ...可以做任何事情,包括增加數量不確定的數量。

可能針對編碼器回退是一個「默認」的情況進行了優化,只是用「?」替換非ASCII字符。雖然。


進一步編輯:我只是試圖混淆這與代理對,希望它會代表一個問號。不幸的是不:

string text = "x\ud800\udc00y"; 
Console.WriteLine(text.Length); // Prints 4 
Console.WriteLine(Encoding.ASCII.GetByteCount(text)); // Still prints 4! 
+0

EncoderFallback無法將單個字節替換爲2個或更多字節。它會像將Æ轉換成AE一樣,但它從來不會做這樣的事情。它只是將ç轉換爲c例如。爲單個字符生成2個字節的表示會破壞很多設計。編輯和文字處理器。如果他們已經考慮到了編碼器後備代碼,他們的代碼應該是目前我們所擁有的代碼。 GetCharCount – TakeMeAsAGuest 2011-04-10 08:09:45

+0

也是如此。我認爲ascii的默認回退不是用一個替換非ASCII字符的方式嗎?它的最佳匹配回退(不知道爲什麼)沒有公開。它產生çc,不是? – TakeMeAsAGuest 2011-04-10 08:14:19

+0

@TakeMeAsAGuest:EncoderFallback *可以*用整個字符串替換單個字符 - 例如'新的EncoderReplacementFallback(「ouch」);'。至於默認替換 - docs聲明「如果使用由Encoding.ASCII屬性或ASCIIEncoding構造函數返回的默認編碼器,那麼在執行編碼操作之前,該範圍之外的字符將被替換爲問號(?)。也許這是不準確的,雖然... – 2011-04-10 08:33:59

1

有趣的是,mono runtime doesn't seem to include that behaviour

// Get the number of bytes needed to encode a character buffer. 
public override int GetByteCount (char[] chars, int index, int count) 
{ 
    if (chars == null) { 
     throw new ArgumentNullException ("chars"); 
    } 
    if (index < 0 || index > chars.Length) { 
     throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array")); 
    } 
    if (count < 0 || count > (chars.Length - index)) { 
     throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array")); 
    } 
    return count; 
} 

// Convenience wrappers for "GetByteCount". 
public override int GetByteCount (String chars) 
{ 
    if (chars == null) { 
     throw new ArgumentNullException ("chars"); 
    } 
    return chars.Length; 
} 

,並進一步向下

[CLSCompliantAttribute(false)] 
[ComVisible (false)] 
public unsafe override int GetByteCount (char *chars, int count) 
{ 
    return count; 
} 
+0

有人可能會中斷他們的實施並提供自定義回退。但我更喜歡這個實現。網絡框架,因爲我懷疑如果在全世界的任何機構爲單個字節編碼和自定義回退爲單字節編碼產生了一個自定義回退和一個自定義回退,這會產生多於一個字節的單個字符 – TakeMeAsAGuest 2011-04-10 11:51:18

+0

看起來@Margus剛剛發佈了一個不錯的關於這個 – sehe 2011-04-10 12:12:10

1

對於多字節字符編碼像UTF8,該方法是有意義的,因爲字符存儲在1到6個字節。我想,該方法也適用於像ASCII這樣的固定大小的編碼,其中每個字符都以7位存儲。然而,在實際實現中,"aaaaaaaa"將是8個字節,因爲ASCII中的字符存儲在1個字節(8位)中,所以lenght hack可以在最好的情況下工作。

以前版本的.NET Framework允許通過忽略第8位來進行欺騙。當前版本已更改,以便在字節解碼期間非ASCII碼點回落。
來源:MSDN

我明白你的問題是:Does worst case scenario exist for lenght hack?

 Encoding ae = Encoding.GetEncoding(
       "us-ascii", 
       new EncoderReplacementFallback("[lol]"), 
       new DecoderReplacementFallback("[you broke Me]")); 

     Console.WriteLine(ae.GetByteCount("õäöü")); 

這將返回20作爲字符串"õäöü"包含4個字符,所有的都關閉"us-ascii"字符集限制(U + 0000U + 007F。),所以在編碼器之後,文本將是"[lol][lol][lol][lol]"

+0

的消息我意識到這一點,我們正在談論框架自己的回退,這是用在%99.999的情況下,我相信 – TakeMeAsAGuest 2011-04-10 11:01:29