http://gsdhaiji-cai.iteye.com/blog/1148049
一、什么是编码
将数据转换为代码或者编码字符,并能译为原数据形式。
问题一:加密解密他也可以做到上面,那加密=编码么?
回答:NO!
编码条件之一它要非常快
编码有与安全无关
不是所有的加密算法都可以还原比如MD5这种散列加密算法,加完密之后就不知道怎么还原了。
二、计算机编码历史
0、更加很久很久以前 为了表示二极管的通、分,表示高电平、低电平,我们引入的1、0编码进行代
1、很久很久以前,也就是上个世纪60年代,人类需要把计算机的0101010与文字进行对应,做出了一套ASCII编码(美国佬做的),他只会对自己的语言进行编码,26个字母、数字、其他符号,只用了7位二进制数搞定,第一位用0表示。 所以ASCII编码最多127编码
2、问题出现了,英文使用ASCII进行编码,那我法文、俄文怎么办?这些国家就基于ASCII编码,利用上ASCII第一位(未使用)变成1,来对自己国家的语言进行编码。
3、每一个国家都基于ASCII,让第一位变成1,问题出现了,同样的一个编码,不同国家代表的不同的文字,你表示你法文的X,我表示我的俄文的X
4、我们中国大陆80年代也开始对文字进行编码,由于我们的文字较多,即使是基于ASCII将第一位变成1,也不够我们使用(国语博大精深拉),所以出现了gb2312编码,使用2个字节
5、我国的港澳地区,他们是使用繁体字,gb2312没有这个繁体字,怎么办了?他们就出了自己的区域编码BIG5
6、中国一统,我要既有简体编码兼容gb2312,又能有繁体编码,后来我国出来了GBK编码,他兼容了绝大部分gb2312编码,所以我们经常有发现gb2312编码的文字用gbk可以读出来
7、世界大统。各国编码个表示个的,这种事情还是需要统一一下吧,于是引入了unicode——(uni统一的意思,code编码)把所有国家的文字都进行了编码。
8、统一是一件好事,但是也是有问题的,比如我英文只要1个字节ASCII编码就可以表示,你unicode还需要2个字节或更多,前面有很多无用的000000000000000000,对吧。
9、解决上面问题,我们引入了utf8编码,是基于unicode的一种优化,英文我给你1个字节,中文我给你2、3个字节。我能屈能伸,我可以变化长度来保存,就不会浪费空间了吧。
UTF-8的编码规则很简单,只有二条:
- 1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
- 2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
- 下表总结了编码规则,字母x表示可用编码的位。
- Unicode符号范围 | UTF-8编码方式
- (十六进制) | (二进制)
- --------------------+---------------------------------------------
- 0000 0000-0000 007F | 0xxxxxxx
- 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
- 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
- 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
u4e00-u9fa5 (中文)绝大部分应该处于这里,但是少部分特殊情况
getBytes是如何转换的呢?
- /**
- * 例1:“汉”字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间,使用用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。
- * 将0x6C49写成二进制是:0110 1100 0100 1001,
- * 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,十六进制E6 B1 89,转换成10进制就是230 177 137.
- *String.getBytes()的结果是怎么得到的呢?
- 上面结果是unsigned char,用-(256-x)再转换成signed char就是-26, -79, -119,也就是String.getBytes()的结果了