为什么IsSingleByte Encoding's GetByteCount做计算

本文关键字:GetByteCount 计算 IsSingleByte Encoding 为什么 | 更新日期: 2023-09-27 17:49:52

我已经检查了AsciiEncoding的GetByteCount方法。它执行长计算,而不是返回String.Length。这对我来说没有任何意义。你知道为什么吗?

为什么IsSingleByte Encoding's GetByteCount做计算

编辑:我刚刚试着复制这个,我目前不能强迫一个ASCIIEncoding而不是有一个不同的替代。相反,我必须使用Encoding。gettencoding来获取一个可变的。所以对于ascii编码,我同意…但是对于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!

有趣的是,mono运行时似乎不包括这种行为:

// 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;
}

对于像UTF8这样的多字节字符编码,此方法是有意义的,因为字符存储在1 - 6字节中。我想,这种方法也适用于固定大小的编码,如ASCII,其中每个字符存储为7位。然而,在实际实现中,"aaaaaaaa"将是8字节,因为ASCII中的字符存储在1字节(8位)中,因此lenght hack将在最佳情况下工作。

以前版本的。net框架允许通过忽略第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]"