【问题标题】:C++ test for validation UTF-8用于验证 UTF-8 的 C++ 测试
【发布时间】:2022-01-31 13:31:58
【问题描述】:

我需要为 UTF-8 验证编写单元测试,但我不知道如何在 C++ 中编写不正确的 UTF-8 案例:

TEST(validation, Tests)
{
    std::string str = "hello";
    EXPECT_TRUE(validate_utf8(str));

    // I need incorrect UTF-8 cases
}

如何在 C++ 中编写不正确的 UTF-8 案例?

【问题讨论】:

  • 您可以使用十六进制或八进制转义序列,例如str = "\200";.
  • 看看bit patterns 的有效二进制UTF-8。 前导位(以黑色显示)承诺一个模式。以颜色显示的位可以是任何东西。
  • 除了校验位模式,还需要拒绝超长码、代理码、0x10FFFF和0xFFFE/0xFFFF以上的值。

标签: c++ testing utf-8 utf


【解决方案1】:

您可以使用十六进制形式的\x 转义序列或八进制形式的\000 转义序列指定字符串中的各个字节。

例如:

std::string str = "\xD0";

这是不完整的 UTF8。

查看 https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt 以获取有效和格式错误的 UTF8 测试用例。

【讨论】:

    【解决方案2】:

    在 UTF-8 中,任何最高有效位为 0 的字符都是普通 ASCII 字符,任何其他字符都是多字节序列 (MBS) 的一部分。

    如果第二个最重要的是另一个,那么这是 MBS 的第一个字节,否则它是后续字节之一。

    在 MBS 的第一个字节中,后续最高有效位的数量为您提供了整个序列的字节数,例如。 G。 0b110xxxxxx 的任意值是两字节序列的起始字节。

    理论上您现在可以生成最多 7 个字节的序列,目前它们被限制为 4 或 5 个字节(此处不完全确定,您需要查找)。

    您现在可以通过定义适当的序列来生成任意代码点,例如"\xc8\x85" 将表示序列0b11001000 0b10000101,这是一个合法模式并表示代码点0b 01000 000101(注意表示UTF-8 标头的前导位是如何被切除的)对应于值0x405 或1029。如果这是一个您需要查找的所有有效代码点,我只是形成了一个任意位模式作为示例。

    现在,您可以通过增加最高有效位的数量和适当数量的后续字节数来表示更长的有效序列(再次注意:初始一位的数量是 total em> 字节数包括 MSB 的第一个字节)。

    同样,您现在生成无效序列,使得序列的总字节数与初始一位数不匹配(太多或太少)。

    到目前为止,您可以生成任意有效或无效序列,其中有效序列代表任意代码点。您现在可能需要查找这些代码点中的哪些实际上是有效的。

    最后,您还可以考虑组合字符(带有变音符号)——它们可以表示为一个字符(不是字节!)或标准化的单个字符——如果你想走那么远,那么你需要在标准哪些组合是合法的并符合哪些规范化代码点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2017-06-18
      • 2014-12-18
      相关资源
      最近更新 更多