[Misc] 字符集,字符编码,UTF 8与Unicode的关系 - Gukie/learning GitHub Wiki

refer

首先,在互联网上能看到的,都是字符; 而他们在传输过程中,比如一个文件从中国传输到美国,在传输前文件里面的字符都是会被编码成一个一个的二进制流,然后再进行传输;

将一个字符,比如 "你好",转为二进制串的过程,就是编码; 反过来,就是解码; 编码跟解码,都需要遵循某个规范,才能正确进行;这就是字符集存在的意义; 大家都在同一个字符集中进行编码与解码,传输者表达的与接受者接收到的,才会是同一个东西;

字符集

字符集,就好比各种语言,比如英语,日语,中文; 它有三个要素:

  • 字库表,即字符数据库
  • 编码字符集,字符在字库表中的位置,即字符在字库表中的索引
  • 字符编码,字符在编码字符集中的值 与 字符在实际存储中对应的数值 之间的一个转化,可以认为字符编码是 编码字符集的一个实现
  • 比如 Unicode中的字符有很多,如果都用统一的编码方式,那么就要按照 能将所有字符中占位最多的字符为准,比如占位最多的字节需要4个字节,那么所有的字符在编码的时候,都需要被编码成4个自己,即使它用一个字节就够了; 这就严重浪费了存储空间; 所以UTF-8的出现就是为了解决这个问题的

Unicode 与 UTF-8

Unicode是一个 编码字符集,它涵盖了几乎世界上所有的字符及其对应的编码; 而UTF-8则是 Unicode的一个实现,UTF-8是一个字符编码

字符编码

  • ASCII,采用一个字节表示,但第一位用0占位; 即它最多表示 127个字符,对于英文字母来说,已经足够
  • 对于欧洲的一些国家的语言,ASCII就支持不了了; 所以它们就将第一个占位符拿过来使用,扩展成256个字符了,这样同一个数值,比如130,代表的单词却会不一样; 所以这时候就需要 编码与解码需要使用同一种字符编码方式,否则就会有乱码的出现
  • 对于一些复杂的语言,比如中文日语,一个字节还是不够,就会出现多个字节的情况; 就出现了其他的字符编码,比如GB2313,GBK

UTF-8

UTF-8的出现,是为了统一互联网上的字符编码,以便不同字符不会出现乱码现象;它是一个可变长的编码方式,如果是英文,编码出来的二进制串还是一个字节; UTF-8 的编码规则很简单,只有二条:

  • 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

  • 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

识别乱码

可以通过SQL语句,将一些乱码进行转义

select hex(convert('璇锋眰瓒呮椂' using gbk)); -- 得到的值是: E8AFB7E6B182E8B685E697B6
select convert(0xE8AFB7E6B182E8B685E697B6 using utf8);