如何生成非UTF-8字符集

Nit*_*thi 14 utf-8

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

lin*_*ski 12

如果你问如何构造一个非UTF-8字符,那么维基百科的这个定义应该很容易:

utf8定义

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

0xxxxxxx   // a
Run Code Online (Sandbox Code Playgroud)

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

110xxxxx 10xxxxxx  // b
Run Code Online (Sandbox Code Playgroud)

等等.

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

10xxxxxx
Run Code Online (Sandbox Code Playgroud)

要么

111xxxxx
Run Code Online (Sandbox Code Playgroud)

这也与两种模式不同.

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

你没有标记语言,但我必须测试它,所以我使用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")
    );
}
Run Code Online (Sandbox Code Playgroud)

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 ?
Run Code Online (Sandbox Code Playgroud)

delete0x7f和之后,从128包含地最多254被印刷没有有效的字符.您还可以从UTF-8图表中看到:

图片

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

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

绝对最低每个软件开发人员绝对必须知道Unicode和字符集(没有借口!)