15

我的要求之一是“文本框名称应仅接受 UTF-8 字符集”。我想通过输入非 UTF-8 字符集来执行否定测试。我怎样才能做到这一点?

4

1 回答 1

12

如果您要问如何构造一个非 UTF-8 字符,那么从 Wikipedia 的这个定义中应该很容易:

utf8 定义

对于代码点 U+0000 到 U+007F,每个代码点都是一个字节长,如下所示:

0xxxxxxx   // a

对于代码点 U+0080 到 U+07FF,每个代码点有两个字节长,如下所示:

110xxxxx 10xxxxxx  // b

等等。

因此,要构造一个非法 UTF-8 字符,长度为一个字节,最高位必须为 1(与模式 a 不同),第二高位必须为 0(与模式 b 不同):

10xxxxxx

或者

111xxxxx

这也不同于两种模式。

使用相同的逻辑,您可以构造超过两个字节长的非法代码单元序列。

您没有标记语言,但我必须对其进行测试,所以我使用了 Java:

for (int i=0;i<255;i++) {
    System.out.println( 
        i + " " + 
        (byte)i + " " + 
        Integer.toHexString(i) + " " + 
        String.format("%8s", Integer.toBinaryString(i)).replace(' ', '0') + " " + 
        new String(new byte[]{(byte)i},"UTF-8")
    );
}

0 到 31 是不可打印字符,然后 32 是空格,后面是可打印字符:

...
31 31 1f 00011111 
32 32 20 00100000  
33 33 21 00100001 !
...
126 126 7e 01111110 ~
127 127 7f 01111111 
128 -128 80 10000000 �

deleteis0x7f和之后,从 128 到 254 不打印有效字符。您还可以从UTF-8 图表中看到:

图片

代码点U+007F用一个字节0x7F(位01111111)表示,而代码点U+0080用两个字节0xC2 0x80(位11000010 10000000)表示。

如果您不熟悉 UTF-8,我强烈建议您阅读这篇优秀的文章:

每个软件开发人员绝对、绝对必须了解 Unicode 和字符集的绝对最低要求(没有借口!)

于 2013-04-16T08:44:13.880 回答