字符编码详解

一些基础概念

1、1个字节有8位,7位就可以表示0-255共256种状态,还有1位可当作符号位/特殊标识位。

2、计算机只能识别二进制,但对于人类来说,一长串的二进制交流起来很费劲,所以通过转换成十六进制来交流。

3、转换:0010 0001,前4位值等于2,后4位值等于1,十六进制就等于21。为了防止误解为十进制数二十一,所以十六进制一般用0x前缀来表示,即0x21。

4、字符集:统一规定二进制值和字符的对应关系,就叫字符集。常见的有ASCII、GBK、Unicode。

5、字符编码:字符集规定了某个值对应某个字符,但是并没有规定这个值要用多少位来显示、每一位代表什么含义等等,字符编码就是规定具体的编码、解码规则。常见的有ASCII、GBK、UTF-8/UTF-16。

ASCII

既是字符集,同时又是字符编码。

作为字符集,规定0-31对应特定动作(比如换行、输出等),32-127对应字母、数字、符号等,后来又扩展了128-255对应欧洲字符。

作为字符编码,规定每个字符由1个字节的8位表示,最高位是校验位,剩余7位的值代表字符。

GBK

计算机传到中国后,有7000多个汉字需要显示,于是就诞生了GBK。同样,既是字符集,有是字符编码。

作为字符集,规定0-127与ASCII一样,127以上的值,分别对应中文、全角标点、罗马字符、日文片假名等等。

作为字符编码,ASCII的字符用1个字节表示,中文用2个字节表示。如果要表示英文,就用1个字节,跟ASCII一样;如果要表示中文,就用两个字节,前一个字节范围0xA1~0xF7,后一个字节范围0xA1~0xFE。所以,当计算机读到一个字节的值小于127(0X7F)时,就知道这是一个单字节字符,读到一个字节的值大于0xA1时,就认为这是一个中文字符的第一个字节。

Unicode

美国有ASCII字符集、中国有GBK字符集、日本台湾等其它国家地区也用自己的字符集,各个字符集之间不能兼容,导致各种不方便,于是诞生了全球统一的字符集Unicode。Unicode收录了全球的字符,任何字符在Unicode字符集中都能找到对应的值。

UTF-32、UTF-16编码

UTF32编码规定每个字符用4个字节共32位来表示,这样很方便,但有个缺点是浪费空间。

UTF-16规定0~65535之间的字符用2个字节表示,包含了绝大多数字符;65535以上的字符需要一些特殊规则处理,通过4个字节来表示,具体规则可以百度。

UTF-8

000000-00007F之间的字符,用0xxxxxxx表示。0是标识位,xxxxxxx部分表示数值;

000080-0007FF之间的字符,用110xxxxx10xxxxxx表示。110、10是标识位,x部分表示数值,解码时,把x部分按顺序连起来,当成二进制值就行了;

000800-00FFFF之间的字符,用1110xxxx 10xxxxxx 10xxxxxx表示;

010000-10FFFF之间的字符,用11110xxx10xxxxxx10xxxxxx10xxxxxx表示。

Emoji

emoji的字符集有很多版本,所以不统一,下面有个过滤emoji的方法。

过滤emoji,通过for循环,判断String里的每一位char是否在emoji区间:

private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }
发布了35 篇原创文章 · 获赞 52 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章