如何检查无效的UTF-8字符?

时间:2018-06-08 12:55:02

标签: c# unicode

现在有很多受支持的十六进制(UTF-8)实体从十进制值0到10175开始,是否有一种快速方法来检查变量中包含的某个值是否是受支持的十六进制值之一( UTF-8)实体。

e.x。

var something="some string value";
char[] validCharacter = new[] { All 10175 UTF-8 Hexadecimal characters };
if(validCharacter.Contains(something))
{ \\do something };

我怎样才能以最快的方式检查?

2 个答案:

答案 0 :(得分:3)

这应该返回你的要求。它将检查是否缺少未配对的高/低代理和缺少未定义的代码点("定义"取决于您正在使用的.NET版本和版本中的unicode表操作系统)

static bool IsLegalUnicode(string str)
{
    for (int i = 0; i < str.Length; i++)
    {
        var uc = char.GetUnicodeCategory(str, i);

        if (uc == UnicodeCategory.Surrogate)
        {
            // Unpaired surrogate, like  ""[0] + "A" or  ""[1] + "A"
            return false;
        }
        else if (uc == UnicodeCategory.OtherNotAssigned)
        {
            // \uF000 or \U00030000
            return false;
        }

        // Correct high-low surrogate, we must skip the low surrogate
        // (it is correct because otherwise it would have been a 
        // UnicodeCategory.Surrogate)
        if (char.IsHighSurrogate(str, i))
        {
            i++;
        }
    }

    return true;
}

请注意,Unicode处于持续扩展状态。 UTF-8能够映射所有Unicode码点,甚至是目前无法分配的码点。

一些例子:

var test1 = IsLegalUnicode("abcdeàèéìòù"); // true
var test2 = IsLegalUnicode("⭐ White Medium Star"); // true, Unicode 5.1
var test3 = IsLegalUnicode(" Beaming Face With Smiling Eyes"); // true, Unicode 6.0
var test4 = IsLegalUnicode(" Slightly Smiling Face"); // true, Unicode 7.0
var test5 = IsLegalUnicode(" Hugging Face"); // true, Unicode 8.0
var test6 = IsLegalUnicode(" Rolling on the Floor Laughing"); // false, Unicode 9.0 (2016)

var test7 = IsLegalUnicode(" Star-Struck"); // false, Unicode 10.0 (2017)

var test8 = IsLegalUnicode("\uFF00"); // false, undefined BMP UTF-16 unicode

var test9 = IsLegalUnicode(""[0] + "X"); // false, unpaired high surrogate pair
var test10 = IsLegalUnicode(""[1] + "X"); // false, unpaired low surrogate pair

请注意,您可以使用UTF-8进行编码,即使是格式良好的&#34;未知&#34; Unicode代码点,如 Star-Struck

在Windows 10下使用.NET 4.7.2获得的结果。

答案 1 :(得分:2)

如果启用了错误检测,UTF8Encoding.GetString(byteArray)将抛出ArgumentException。

来源:https://msdn.microsoft.com/en-us/library/kzb9f993(v=vs.110).aspx

但是,如果您正在测试已经是字符串的内容 - 据我所知 - 它几乎总是有效的UTF8。 (见下文。)据我所知,所有C#字符串都以UTF16编码,UTF16是所有Unicode字符的编码。 UTF8只是同一组的不同编码。即对于所有Unicode字符。

(这可能会排除一些新的Unicode字符等等。但这些字符也不会出现在UTF16中,因此在这里无关紧要。)

正如有人评论的那样,可能会有一半&#34; UTF16字符,它们是有效的字符串,但不是有效的UTF8值。因此,您可以Encoding.Unicode.GetBytes()然后Encoding.UTF8.GetString()进行验证。但那些可能很少见。