常用编码的种类
ASCII
ASCII码使用7位2进制数表示一个字符,7位2进制数可以表示出2的7次方个字符,共128个字符,最高位的1没有用。取值范围: 0X00-0X7F
EBCDIC(Extended Binary Coded Decimal Interchange Code)
(iso-8859-1)有些情况也叫Latin-1
n 因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。
n 0X00-0X7F前面的和ASCII完全兼容
GB2312 是对 ASCII 的中文扩展
(非定长编码)
规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。
GBK(GB18030 少数民族的字也加进去了)
由于中国字太多如繁体,于是干脆不再要求低字节一定是127号之后的码,只要第一个字节是大于127就固定表示这是一个汉字的开始,
UCS (Universal Multiple-Octet Coded Character Set),俗称 "UNICODE"
就是16位来统一表示所有的字符,对于ascii里的那些“半角”字符,UNICODE 包持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。(编码不兼容)由于“半角”英文符号只需要用到低8位,所以其高 8位永远是0,因此这种方案在保存英文文本时会多浪费一倍的空间。
ISO已经准备了UCS-4方案,说简单了就是四个字节来表示一个字符.
UTF(UCS Transfer Format)
UTF(UCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到 UTF时并不是直接的对应,而是要过一些算法和规则来转换。
n 转换规则"联通"的内码是:
n c1 1100 0001
n aa 1010 1010
n cd 1100 1101
n a8 1010 1000
常用编码的种类
n 5、UTF的字节序和BOM
n
n UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是 “乙”?
n 在UCS 编码中有一个叫做“ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符“ZERO WIDTH NO-BREAK SPACE”。
n 这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。
n 因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
n UTF -8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符“ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF。
n 所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。Windows就是使用BOM来标记文本文件的编码方式的。
乱码并不可恢复的原因:
用了不兼容的编码,错误的理解导致部分编码遗失。
各部分编码问题:
(1) java 类.class
大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。Java的JDK和JVM即是如此.
Java语言内部采用UNICODE编码
(2)浏览器
几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递。
(3)编辑软件java源文件
【eclipse】
(4) Tomcat
如果程序中没有设定接受参数时采用的编码格式,则WEB容器会默认采用ISO-8859-1编码格式来接受传入的值并在JVM中转化为UNICODE格式的保存在WEB容器的内存中
(5) Java和数据库之间
和驱动程序有关。(数据库编码)
(6)jsp
自己设定的。