食品行业网站建设方案,樱花动漫做网站,厦门seo公司到1火星,网站建设中 动画编码#xff1a;数据存储进计算机中需要转换为二进制存储#xff0c;这个过程就是编码。 解码#xff1a;计算机读取数据并展示在页面上#xff0c;需要将二进制转换为人类语言的过程#xff0c;叫做解码。 乱码#xff1a;如果编码和解码时使用的码表不一样#xff0c;…编码数据存储进计算机中需要转换为二进制存储这个过程就是编码。 解码计算机读取数据并展示在页面上需要将二进制转换为人类语言的过程叫做解码。 乱码如果编码和解码时使用的码表不一样就会产生乱码。 码表就是将人类可以看懂的数据格式转换成计算机能够认识的二进制形式的参考表称为码表。
ASCII
American Standard Code for Information Interchange美国信息交换标准代码。
计算机发明之初基本只考虑了美国的需求而美国大概只需要 128 个字符用 7 位刚好可以表示计算机存储的最小单位是 byteASCII 中最高位设置为 0剩下的 7 位表示字符ASCII 码规定了 0 ~ 127 对应的字符。
数字 32~126 表示的字符都是可打印字符。 0~31 和 127 表示一些不可打印的字符。
数字缩写/字符解释转义字符0NULnull空字符\08BSbackspace退格\b9HThorizontal tab水平制表符\t10LFNL line feednew line换行键\n13CRcarriage return回车键\r27ESC换码127DELdelete删除
ASCII 码对美国够用但对其他国家是不够的。
各国的计算机厂商发明了各自的编码方式以表示自己国家的字符为了保持与 ASCII 码的兼容性一般都是将最高位设置为 1。
就是说当最高位为 0 时表示 ASCII 码当为 1 时就是各个国家自己的字符。
ISO 8859-1
ISO 8859-1 又称 Latin-1同样使用一个字节表示一个字符。
其中 0127 与 ASCII 一样128255 规定了不同的含义。
Windows-1252
基本上可以认为ISO8859-1 已被 Windows-1252 取代在很多应用程序中即使文件声明它采用的是 ISO 8859-1 编码解析的时候依然被当作 Windows-1252 编码。
GBK
GBK 使用固定的两个字节表示字符高位字节范围是 0x810xFE 低位字节范围是 0x400x7E 和 0x800xFE。
需要注意的是低位字节是从 0x40即64开始的因此低位字节的最高位可能为 0如何判断它是汉字还是 ASCII 字符呢因为汉字是用固定两个字节表示的当第一个字节的最高位为 1 时直接将下一个字节一起解析然后跳到第三个字节继续解析。
Unicode
Unicode 给世界上所有字符都分配了一个唯一的数字编号编号范围从 0x0000000x10FFFF。
每个字符都有一个 Unicode 编号这个编号一般写成十六进制在前面加 U比如“马”的 Unicode 编码是 U9A6C。
Unicode 给字符分配了统一的数字编号但它并没有规定这个编号怎么对应到二进制表示。
编号怎么对应到二进制表示主要方案有 UTF-32、UTF-16 和 UTF-8 。
UTF-32
字符 Unicode 编号的整数二进制形式4个字节根据字节排序的不同大端和小端分为 UTF-32BE 和 UTF-32LE。
UTF-16
UTF-16 使用变长字节表示。对于编号在 U0000 ~ UFFFF的字符常用字符直接用 2 个字节表示UD800UDBFF的编号其实是没有定义的。
编号在 U10000 ~ U10FFFF的字符增补字符集需要使用 4 个字节表示前两个字节叫高代理项范围是UD800UDBFF后两个字节叫低代理项范围是UDC00UDFFF。
区分是2个字节还是4个字节表示一个字符就看前两个字节的编号范围如果是UD800UDBFF就是4个字节否则就是2个字节。
UTF-16也有和UTF-32一样的字节序问题如果高位存放在前面就叫大端BE编码就叫UTF-16BE否则就叫小端编码就叫UTF-16LE。
UTF-8
UTF-8 使用变长字节表示字符使用的字节个数与其 Unicode 编号的大小有关编号小的使用的字节就少字节个数为 14 不等。
编号范围二进制格式0x00 ~ 0x7F0 ~ 1270xxx xxxx0x80 ~ 0x7FF128 ~ 2047110x xxxx 10xx xxxx0x800 ~ 0xFFFF2048 ~ 655351110 xxxx 10xx xxxx 10xx xxxx0x10000 ~ 0x10FFFF65536以上1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
上表中x 表示可以用的二进制位而每个字节开头的1或0是固定的。
UTF-8 将字符看作整数转化为二进制形式去掉高位的 0然后将二进制位从右向左依次填入对应的二进制格式 x 中填充完后如果对应的二进制格式还有没填的 x则设为 0。
/*如 马 的 Unicode 编号是 0x9A6C整数编号是 39532二进制 1001 101001 101100对应的 UTF-8 二进制格式是1110 xxxx 10xx xxxx 10xx xxxx将二进制 1001 101001 101100 从右到左依次填入二进制格式中结果就是其 UTF-8 编码1110 1001 1010 1001 1010 1100*/UTF-8 是兼容 ASCII 的对大部分中文字符而言需要使用三个字节表示。
Java 中的编码
Java 源码可以使用任何形式的编码默认使用的是电脑系统自带的编码。
源码编译后生成 .class 文件.class 文件中字符编码为 modified UTF-8它类似于 UTF-8但是二者不同。
JVM 运行的时候将 modified UTF-8 解码成 UTF-16UTF-16 编码是字符 char 在内存中的编码形式。
总结就是源代码从【某种编码方式】编码成 modified UTF-8 再到 modified UTF-8 解码成执行期的 UTF-16便于统一处理。
编码转换
不同编码格式之间可以借助 Unicode 编号进行编码转换。可以认为每种编码都有一个映射表存储 Unicode 编号和其特有的字符编码之间的对应关系。
编码转换的具体过程可以是一个字符从 A 编码转到 B 编码先找到字符的 A 编码格式通过 A 编码的映射表找到其 Unicode 编号然后通过 Unicode 编号再查找 B 编码的映射表找到字符的 B 编码格式。
乱码问题
解析错误
使用错误的编码进行解析比如小明采用 Windows-1252 写了个文件发送给了小红小红使用 GBK 来解析这个字符看到的可能就是乱码。
编码转换错误
在错误解析的基础上还进行了编码转换。比如文件实际是 Windows-1252编码小红用 GBK 解析打开后看到乱码又转换成了 UTF-8 编码。
乱码恢复
恢复要抓住两个关键信息一个是原来的二进制编码方式A另一个是错误解读的编码方式B。
public static void recover(String str) throws UnsupportedEncodingException {String[] charsets {windows-1252, GB18030, Big5, UTF-8};for(int i 0; i charsets.length; i){for(int j 0; j charsets.length; j){if(i ! j){String s new String(str.getBytes(charsets[i]), charsets[j]);System.out.println(---- 原来编码(A)假设是 charsets[j] , 被错误解读为了(B): charsets[i]);System.out.println(s);System.out.println();}}}
}