编码与解码
编程语言内置编码(欢迎不同语言的小伙伴分享各语言的内置编码方式)
Java中
- 编译生成的.class文件统一采用Unicode编码,即UTF-16,Unicode编码中包含了中文的常用的汉字
一、基础概念
字节Byte 是存储容量的基本单位(B),1字节 = 8bit
字符 是指计算机中使用的文字和符号,比如1、2、3、A、b、(、)
编码、解码
编码是信息从一种形式转换为另一种形式的过程。不同字符对应的二进制数的规则。
解码是编码的逆过程,它是将存储在计算机的二进制转换为可以看到的字符。
乱码,本质是编码解码采用的格式不统一造成的。
字符集 字符编码的集合就是字符集,每个字符集包含的个数不同,计算机处理各种字符集文字,便需要进行编码。常见的字符集名称有:ASCII字符集、GB2312字符集、GB18030字符集、Unicode字符集、GBK字符集等。
二、常见的几种编码解析
-
ASCII
单字节编码,用一个字节的低 7 位表示,该字符集共有 128 个字符。其中,0~31 是控制字符如换行、回车、删除等;32~126 是打印字符,可以通过键盘输入并且能够显示出来。 -
ISO8859_1 (扩展ASCII编码)
它是ISO 组织在 ASCII 码基础上制定了一些列标准用来扩展 ASCII 编码,
它们是 ISO-8859-1~ISO-8859-15,其中 ISO-8859-1 涵盖了大多数西欧语言字符,所以应用的最广泛。依然属于单字节编码,最多能表示256个字符,范围是0-255,很明显,Iso8859_1编码表示的范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,很多协议默认使用该编码,如HTTP协议、浏览器的默认编解码方式。 -
GB2312/GBK
GB2312,双字节编码,共收录了6763个汉字,是汉字的国际码,专门用来表示汉字,是中国国家标准简体中文字符集,其英文字母同Iso8859_1(兼容Iso8859_1),即单字节,故而GB2312 并非定长编码。GBK是汉字内码扩展规范,K 为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母,编码用来同时表示繁体字和简体字,共收录了21003个字节,而GB2312只能表示简体字,
GBK是兼容GB2312的。 -
UniCode
这是最统一的编码,又称统一码、万国码、单一码,它是业界的一种标准,是为了解决传统的字符编码方案的局限而产生的,用来表示所有语言的字符,是定长双字节(也有四字节)编码,包括英文字母在内也是***双字节编码***,所以它是不兼容Iso8859_1编码的,也不兼容任何编码。不过,相对于iso8859_1,unicode编码只是在前面加了一个 0 字节。比如字符a 为 00 61。
需要说明的是,定长编码便于计算机处理(GB2312/GBK不是定长编码),而unicode编码又可以表示所有字符,所以在很多软件***内部都是使用unicode编码来处理的,比如Java***。 -
UTF系列
考虑到unicode编码不兼容iso8859-1编码,而且容易占用更多的空间,因为对于英文字母,unicode也需要两个字节表示,所以unicode不便于传输和存储,因此产生了UTF编码,它是unicode的实现方式,Unicode Transformation Format(简称 UTF)。UTF编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符,不过utf 是不定长编码,每个字符的长度从1-6个字节不等。另外,utf编码自带简单的校验功能,一般来讲,英文字母都用一个字节表示,而汉字使用3个字节。
注意,虽然说utf是为了使用更少的空间而使用的,但那只是相对于unicode编码来说,如果已经知道是汉字, 则使用GB2312、GBK无疑是最节省的。 -
unicode是字符集,它主要有utf-8/utf-16/utf-32三种实现方式。Java的class文件使用utf-8编码方式,JVM运行时采用utf-16。
UTF-16
UTF-16 具体定义了 Unicode 字符在计算机中存取方法。UTF-16 用两个字节来表示 Unicode 转化格式,这个是定长的表示方法,不论什么字符都可以用两个字节表示,两个字节是 16 个 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作,这也是 Java 以 UTF-16 作为内存的字符存储格式的一个很重要的原因。
UTF-8
UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符可以是由 1~6 个字节组成。
对于单字节的字符,字节的第一位设为0,后面7位为这个符号的unicode码,因此,对于英文字母,utf-8编码和ASCII码相同。
对于n字节的字符(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10,剩下的全部为这个符号的unicode编码。
示例:已知 “严” 的unicode编码是 4E 25(01001110 00100101),它的utf-8编码需要3个字节,格式是1110xxxx 10xxxxxx 10xxxxxx,然后从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0,故而得到的“严”的UTF-8编码为 11100100 10111000 10100101,转换为16进制为E4B8A5。
所以:
- 如果一个字节,最高位(第 8 位)为 0,表示这是一个 ASCII 字符(00 - 7F)
- 如果一个字节,以 11 开头,连续的 1 的个数暗示这个字符的字节数,例如:110xxxxx 代表它是双字节 UTF-8 字符的首字节;
- 如果一个字节,以 10 开始,表示它不是首字节,需要向前查找才能得到当前字符的首字节 。
UTF-32 对每个字符都使用4字节进行编码
- 中文出现乱码情形
可参考这个:http://blog.csdn.net/lwj734114646/article/details/51312970