美文网首页
日拱一卒:特殊字符校验

日拱一卒:特殊字符校验

作者: Tinyspot | 来源:发表于2023-02-27 20:47 被阅读0次

1. 字符集与字符编码

1.1 字符集(Charset)

  • 字符集是一个系统支持的所有抽象字符的集合(即字符的集合)
  • 字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等
  • 字符集分类:
    • ASCII字符集
    • Unicode 字符集
    • GB2312字符集
    • ...

1.2 字符编码(Character Encoding)

字符编码就是将符号转换为计算机能识别的二进制编码
编码(Encoding),将数字映射到字符

2. UTF-8 编码

UTF-8 特点:可变长编码,使用1~4个字节表示一个符号,根据不同的符号而变化字节长度

2.1 UTF-8的编码规则

  1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的Unicode码,对于英文字母,UTF-8编码和ASCII码是相同的。
  2. 对于 n 字节的符号(n > 1),第一个字节的前n位都设为1,第 n+1 位设为0,后面字节的前两位一律设为10,剩下的二进制位就是这个符号的 Unicode 码

2.2 Unicode编码 与 UTF-8 编码对照表

UTF-8 编码把一个 Unicode 字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节

Unicode UTF-8(二进制)
U+0000 – U+007F 0xxxxxxx
U+0080 – U+07FF 110xxxxx 10xxxxxx
U+0800 – U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+10000 – U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

3. 字节处理

/**
 * 11110xxx => 0xF0
 */
@Test
public void convert2() {
    System.out.println(0xF0);
    System.out.println(Integer.valueOf("F0", 16));
    System.out.println(Integer.toBinaryString(Integer.valueOf("F0", 16)));
}

3.1 byte 转换为 Int

@Test
public void byteToInt() {

    // 默认转换
    byte b = -3;
    int i = b;

    // 强制转换
    byte b2 = -3;
    int i2 = (int) b2;
    System.out.println(i2);

    // 无符号转换
    i = Byte.toUnsignedInt(b);
    System.out.println(i); // 253
}

3.2 生僻字判断

@Test
    public void check() {
        printBinary("E0");
        printBinary("C0");
        printBinary("F0");
        printBinary("F7");
        printBinary("F8");
        printBinary("FB");
        printBinary("FC");
        printBinary("FD");

        System.out.println(uncommonChar("\uD844\uDEFE"));
        System.out.println(contain4BytesChar("别墅\uD844\uDEFE"));
    }
    private void printBinary(String hex) {
        Integer i = Integer.valueOf(hex, 16);
        System.out.println("hex: "+ hex + "; i: " + i + "; 二进制:" +Integer.toBinaryString(i));
    }

    /**
     * 正常汉字是三个字节,生僻字一般是 4-6 个字节
     *
     * 1字节 0xxxxxxx
     * 2字节 110xxxxx 10xxxxxx
     * 3字节 1110xxxx 10xxxxxx 10xxxxxx
     * 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
     * 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
     * 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
     */
    public static boolean uncommonChar(String data) {
        if (StringUtils.isBlank(data)) {
            return false;
        }
        byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
        for (byte b : bytes) {
            int i = Byte.toUnsignedInt(b);
            return (0xf0 <= i && i <= 0xf7) // 4字节开头
                    || (0xf8 <= i && i <= 0xfb) // 5字节开头
                    || (0xfc <= i && i <= 0xfd);//6字节开头
        }
        return false;
    }

    /**
     * 是否包含4字节字符
     */
    public static boolean contain4BytesChar(String data) {
        if (StringUtils.isBlank(data)) {
            return false;
        }
        try {
            byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
            for (int i = 0; i < bytes.length; i++) {
                byte bt = bytes[i];
                if ((bt & 0xE0) == 0xC0) {
                    // 两个字节就跳过一个字节
                    i++;
                } else if ((bt & 0xF0) == 0xE0) {
                    // 三个字节就跳过两个字节
                    i += 2;
                } else if ((bt & 0xF8) == 0xF0) {
                    // 检测到四个字节
                    return true;
                }
            }
        } catch (Exception e) {

        }
        return false;
    }

相关文章

  • 常用正则

    校验数字 校验字符 特殊需求 其他

  • 日拱一卒英语社群复盘ing

    相 信 我,你 并 不 孤 独。 日拱一卒启动仪式1-4合集 日拱一卒”英语社群入群作业 日拱一卒启动仪式1-4合...

  • 日拱一卒

    日拱一卒是一个成语,完整的表述是:日拱一卒,功不唐捐。源于《法华经》 :“日拱一卒无尽有,功不唐捐终入海”。 会下...

  • 2017-10-11

    持之以恒,日拱一卒。

  • 2017-10-11

    持之以恒,日拱一卒。

  • 今晚,信仰

    如题,日拱一卒

  • 感觉要重新开始写作了

    按兴趣日拱一卒

  • 坚持还是放弃?取舍之间彰显大智慧。

    今天看到一段话,感觉写的更好,分享给大家。“日拱一卒”源于《法华经》:日拱一卒,功不唐捐——日拱一卒无有尽,功不唐...

  • 日拱一卒

    日拱一卒 任务0(12月11日) 最近刚加入这个“日拱一卒”的社群,名字非常好,学英文就...

  • 无题

    日拱一卒,功不唐捐。

网友评论

      本文标题:日拱一卒:特殊字符校验

      本文链接:https://www.haomeiwen.com/subject/htlkldtx.html