我们入门学习是最常用的一种编码方式,因为1位二进制数可以表示2^n种状态:0、1;而2位二进制数可以表示2^2=4种状态:00、01、10、11;依次类推,7位二进制数可以表示2^7=128种状态,每种状态都唯一地编为一个7位的二进制码,对应一个字符(或控制码),这些码可以排列成一个十进制序号0~127。所以,7位ASCII码是用七位二进制数进行编码的,可以表示128个字符。
即一个字节表示一个字符。
String testString = "fuck你奶奶"; byte b[] = testString.getBytes("ASCII"); //转化为一个个字节 for(int i=0;i<b.length;i++){ System.out.println("字节为:"+b[i]); } String dis = new String(b); System.out.println("转化回来的是:"+dis);
结果就是:
字节为:102 字节为:117 字节为:99 字节为:107 字节为:63 字节为:63 字节为:63 转化回来的是:fuck???
因为ASCII码,将“你奶奶”中文里面的一个字符也只看作一个字节。
包含了世界上的所有语言编码,目前实际应用的Unicode版本对应于UCS-2,使用16位的编码空间。也就是每个字符占用2个字节。这样理论上一共最多可以表示216即65536个字符。基本满足各种语言的使用。实际上目前版本的Unicode尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。Unicode的实现方式称为Unicode转换格式(Unicode Translation Format,简称为UTF)。
即:Unicode编码的无论是英文、数字还是汉字,全部由2个字符表示。
String testString = "fuck你奶奶"; byte b[] = testString.getBytes("Unicode"); //转化为一个个字节 for(int i=0;i<b.length;i++){ System.out.println("字节为:"+b[i]); } String dis = new String(b);
输出为:
字节为:-2 字节为:-1 字节为:0 字节为:102 字节为:0 字节为:117 字节为:0 字节为:99 字节为:0 字节为:107 字节为:79 字节为:96 字节为:89 字节为:118 字节为:89 字节为:118
但是我们会发现,转化的时候之前的两位多了一个 -2 -1
因为:如果一个仅包含基本7位ASCII字符的Unicode文件,如果每个字符都使用2字节的原Unicode编码传输,其第一字节的8位始终为0[7位ASCII只占一个字节的前7位,高位致0]。这就造成了比较大的浪费。对于这种情况,可以使用UTF-8编码,这是一种变长编码,它将基本7位ASCII字符仍用7位编码表示,占用一个字节(首位补0)。而遇到与其他Unicode字符混合的情况,将按一定算法转换,每个字符使用1-3个字节编码,并利用首位为0或1进行识别。这样对以7位ASCII字符为主的西文文档就大大节省了编码长度。
UTF-8是UNICODE的一种变长字符编码又称万国码,如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。
String testString = "fuck你奶奶"; byte b[] = testString.getBytes("UTF-8"); //转化为一个个字节 for(int i=0;i<b.length;i++){ System.out.println("字节为:"+b[i]); } String dis = new String(b);
结果为:
字节为:102 字节为:117 字节为:99 字节为:107 字节为:-28 字节为:-67 字节为:-96 字节为:-27 字节为:-91 字节为:-74 字节为:-27 字节为:-91 字节为:-74
即:我们可以看得出来,英文数字用两个字节表示,中文用三个字节表示。
GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。
String testString = "fuck你奶奶"; byte b[] = testString.getBytes("GBK"); //转化为一个个字节 for(int i=0;i<b.length;i++){ System.out.println("字节为:"+b[i]); }
结果为:
字节为:102 字节为:117 字节为:99 字节为:107 字节为:-60 字节为:-29 字节为:-60 字节为:-52 字节为:-60 字节为:-52
即:一字符都是用两个字节表示
String testString = "fuck你奶奶"; byte b[] = testString.getBytes("GB2312"); //转化为一个个字节 for(int i=0;i<b.length;i++){ System.out.println("字节为:"+b[i]);
结果为:
字节为:102 字节为:117 字节为:99 字节为:107 字节为:-60 字节为:-29 字节为:-60 字节为:-52 字节为:-60 字节为:-52
编码规则类似GBK
ISO/IEC 8859-1,又称Latin-1或“西欧语言”,是国际标准化组织内ISO/IEC 8859的第一个8位字符集。它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入192个字母及符号,藉以供使用变音符号的拉丁字母语言使用。
String testString = "fuck你奶奶"; byte b[] = testString.getBytes("ISO-8859-1"); //转化为一个个字节 for(int i=0;i<b.length;i++){ System.out.println("字节为:"+b[i]); }
结果为:
字节为:102 字节为:117 字节为:99 字节为:107 字节为:63 字节为:63 字节为:63
即:所有的字符都用一个字节表示。