编码与解码本质
编码与解码的本质
问题1:计算机如何用0/1表示字符等人类能看懂的信息?为什么有编码/解码?
前提,计算机只能处理二进制的0/1数据;但是人并不能看懂0101;计算机如何表示字符呢?
为了让人可以操作计算机,就提出一种方案:固定的0101数字串代表固定的字母,字符,符号;这样人就能看懂了;
于是乎就有了Unicode方案,UTF-8方案,GBK方案;
编码和解码的存在就是让人和计算机能够联通!是2端的翻译!
编码的实质就是一种转换标准,什么样的二进制数字串,代表什么样的信息;将机器语言转换为人的语言;
解码的实质也是一种标准,将字符,符号等转换成机器语言。
这就引出2个概念:字符集charset,字符集编码charset encoding
问题2:什么是字符集?
字符集:需要转换成二进制0/1码的字符的集合
问题3:什么是字符集编码?
字符集编码:对字符集应用什么编码规则编码;就是问题1中的方案;
字符集编码就是编码规则,如Unicode,UTF-8,GBK等等
问题4:不同编码的区别是什么?
字符集=>编码规则=>字符集对应码值 集合
不同主要有3个:
1)字符集容量不同
字符集能表示的字符数量不同
字符集:就是字符的集合,比如全人类所有的字符的集合,数量是1000个;
编码规则:ISO,UTF-8,GBK
不同编码规则对应的字符集不同,有的字符集只选择800个字符编码,有的选择900个;
2)不同字符集编码后字符所占存储空间不同
原则上,字符集容量越大,单位信息(如字符)需要二进制数据表示的信息的位数越多,所占空间就越大,无论内存还是磁盘
如:
①ASCII码中,英文字母(不分大小写)占一个字节的空间,中文汉字占两个字节的空间。
②UTF-8编码中,一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。
③Unicode编码中,一个英文等于两个字节,一个中文(含繁体)等于两个字节。
3)计算机计算速度不同
因为存储空间大小不同,计算机处理的速度也不同;
32位处理器一次处理的数据宽度是32,也就是32bit;4个字节
场景是2个字符首位连接的操作;
1个字符占1个字节,一次计算覆盖4个字符
1个字符占2个字节,一次计算覆盖2个字符
所以计算速度肯定不一样!!
字符集的定长与变长,容量与效率
https://my.oschina.net/goldenshaw/blog/307708
问题5:字符集与存储空间的选择
编程中一般默认编码规则选择为UTF-8,这样完美避免了乱码问题!
英文字母 汉字
GBK 1个字节 2个字节
UTF-8 1个字节 3个字节
如果存储大部分是中文的话,字符集可以选择GBK
如果大部分是英文的话,可以选择UTF-8
MYSQL性能
GBK是定长字符集,UTF8是变长字符集,如果数据库需要做大量的字符运算、比较、排序等等,选择定长字符集会更好,因为定长字符集处理速度要比变长字符集处理速度快。
问题6:GBK存储英文占1个字节还是2个字节?
字符串类 String 中的内容是 UNICODE 字符串:
// Java 代码,直接写中文 String string = "中文123"; // 得到长度为 5,因为是 5 个字符 System.out.println(string.length()); |
字符串 I/O 操作,字符与字节转换操作。在 Java 包 java.io.* 中,以“Stream”结尾的类一般是用来操作“字节串”的类,以“Reader”,“Writer”结尾的类一般是用来操作“字符串”的类。
// 字符串与字节串间相互转化 // 按照 GB2312 得到字节(得到多字节字符串) byte [] bytes = string.getBytes("GB2312"); // 从字节按照 GB2312 得到 UNICODE 字符串 string = new String(bytes, "GB2312"); // 要将 String 按照某种编码写入文本文件,有两种方法: // 第一种办法:用 Stream 类写入已经按照指定编码转化好的字节串 OutputStream os = new FileOutputStream("1.txt"); os.write(bytes); os.close(); // 第二种办法:构造指定编码的 Writer 来写入字符串 Writer ow = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312"); ow.write(string); ow.close(); |
问题7:常用字符集
1, 常用字符集分类
ASCII及其扩展字符集
作用:表语英语及西欧语言。
位数:ASCII是用7位表示的,能表示128个字符;其扩展使用8位表示,表示256个字符。
范围:ASCII从00到7F,扩展从00到FF。
ISO-8859-1字符集
作用:扩展ASCII,表示西欧、希腊语等。
位数:8位,
范围:从00到FF,兼容ASCII字符集。
GB2312字符集
作用:国家简体中文字符集,兼容ASCII。
位数:使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。
范围:高字节从A1到F7, 低字节从A1到FE。将高字节和低字节分别加上0XA0即可得到编码。
BIG5字符集
作用:统一繁体字编码。
位数:使用2个字节表示,表示13053个汉字。
范围:高字节从A1到F9,低字节从40到7E,A1到FE。
GBK字符集
作用:它是GB2312的扩展,加入对繁体字的支持,兼容GB2312。
位数:使用2个字节表示,可表示21886个字符。定长。
范围:高字节从81到FE,低字节从40到FE。
GB18030字符集
作用:它解决了中文、日文、朝鲜语等的编码,兼容GBK。
位数:它采用变字节表示(1 ASCII,2,4字节)。可表示27484个文字。
范围:1字节从00到7F; 2字节高字节从81到FE,低字节从40到7E和80到FE;4字节第一三字节从81到FE,第二四字节从30到39。
UCS字符集
作用:国际标准 ISO 10646 定义了通用字符集 (Universal Character Set)。它是与UNICODE同类的组织,UCS-2和UNICODE兼容。
位数:它有UCS-2和UCS-4两种格式,分别是2字节和4字节。
范围:目前,UCS-4只是在UCS-2前面加了0×0000。
UNICODE字符集
作用:为世界650种语言进行统一编码,兼容ISO-8859-1。
位数:UNICODE字符集有多个编码方式,分别是UTF-8,UTF-16和UTF-32。
2 ,按所表示的文字分类
语言 字符集 正式名称
英语、西欧语 ASCII,ISO-8859-1 MBCS 多字节
简体中文 GB2312 MBCS 多字节
繁体中文 BIG5 MBCS 多字节
简繁中文 GBK MBCS 多字节
中文、日文及朝鲜语 GB18030 MBCS 多字节
各国语言 UNICODE,UCS DBCS 宽字节
参考
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
Unicode 和 UTF-8 有何区别? - 于洋的回答 - 知乎
https://www.zhihu.com/question/23374078/answer/69732605
MySQL字符集UTF8与GBK之间如何选择
http://www.qttc.net/201207125.html
计算机字符与编码总结
http://blog.csdn.net/flyeek/article/details/44058153