常见字符集和编码方式

常见字符集和编码方式

ASCIIUnicodeGBKGBK2312UTF-8这些字符集和编码方式的名词总是让我们纠结,那么他们有什么区别呢?


一般来讲,除了UTF-8是字符集Unicode的编码方式,其余的例如ASCIIGBK等都属于字符集,它们为每一个字符集的字符都赋予了一个值,这个值可以是一个字节大小
,也可能是两个字节、三个字节等;

  • 基础的ASCII字符集是单字节字符集,用一个7位二进制数表示128个字符;
  • Unicode旨在包含表示世界上所有语言的的字符,目前主要有UCS-2UCS-4,分别采用两个字节和四个字节来表示每一个字符;
  • GBK2312是采用两个大于127字节来表示汉字,一个小于或等于127的字节维持ASCII的语义的一种字符集;
  • GBKGBK2312的一种扩展,要求高低两字节中的,低字节不需要是大于127的字节,因此表示的字符数得到扩展;
  • UTF8Unicode字符集的一种编码方式,以便于适合在网络上传输和电脑存储;

Unicode字符集和UTF8编码有很强的联系;具体联系是这样的:

  1. 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;
  2. n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,
    这n个字节的其余空位填充该字符unicode码,高位用0补足
    这样就形成了如下的UTF-8标记位:
Unicode(16进制)UTF8(2进制)
0x0000 - 0x007F 0xxxxxxx
0x0080 - 0x07FF 110xxxxx 10xxxxxx
0x0800 - 0xFFFF 1110xxxx 10xxxxxx 10xxxxxx
0x010000 - 0x10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
…… ……

Unicode中大部分汉字是采用2字节表示的,因此UTF8编码后大小是3字节;
但是有些少数不常见的汉字是采用3字节表示的,因此UTF8编码后大小是4字节;

例子:

public static String byteArray2BinaryString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(Integer.toBinaryString(Byte.toUnsignedInt(b)));
            sb.append(" ");
        }
        return sb.toString();
    }

汉字:��

System.out.println("Unicode: " +  Long.toBinaryString((long)"��".codePointAt(0)));
System.out.println("UTF8: " + byteArray2BinaryString("��".getBytes("utf8")));

输出如下:

Unicode: 100000000010111111
UTF8: 11110000 10100000 10000010 10111111

��的Unicode值是100000**000010**111111一共18位,因此是3字节字符;对应的UTF8编码是4字节,因此格式为:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx;
unicode补全成对应的UTF8编码后是:
11110**000** 10**100000** 10**000010** 10**111111**


对于常见的汉字,一般来讲GBK编码比UTF8编码少一个字节(utf8= 1.5 * gbk),因此有时候采用GBK编码来节省带宽和存储空间;对于英文字符,两者编码都是采用单字节来编码,因此无异;

例子:
对于汉字 分别进行UTF8GBK编码

System.out.println("UTF8: " + byteArray2BinaryString("中".getBytes("utf8")));
System.out.println("GBK: " + byteArray2BinaryString("中".getBytes("gbk")));

输出如下:

UTF8: 11100100 10111000 10101101 
GBK: 11010110 11010000 

总结:
- UTF8Unicode字符集的一种编码方式,主要用与信息传输和存储;
- GBK编码对于汉字要比UTF8节省空间,但是不是全球通用,有些环境下会出现乱码;
- UTF-8中大部分汉字采用3字节表示,少些复杂的字采用4字节表示;分别对应的Unicode也是2字节和3字节;

原文地址:https://www.cnblogs.com/Spground/p/8536150.html