前言

作为一个开发人员或是测试人员,免不了要与各种各样的编码打交道,而且这些各种编码总是让人头大,现在我们就来揭开他们的庐山真面目

移动还是联通?

在开始本文前,我需要大家思考一个问题:你知道联通为什么干不过移动吗?
我们来看看微软站在哪边吧,用记事本写下联通两个字:

保存后再从新打开刚刚的文件,你会发现微软表态了:

微软的意思大概就是,联通是啥玩意儿?同样的方法,移动就没毛病。想知道为什么吗?那就要仔细往下看了

ascii

很久以前,计算机制造商有自己的表示字符的方式。他们并不需要担心如何和其它计算机交流,并提出了各自的 方式来将字形渲染到屏幕上。随着计算机越来越流行,厂商之间的竞争更加激烈,在不同的计算机体系间转换数 据变得十分痛苦,人们厌烦了这种自定义造成的混乱,于是就有人站出来阻止这种混乱,他振臂高呼,组织各大厂商开始统一编码,与秦始皇统一文字与异曲同工之妙,他们用一个字节来表示他们使用的字符,a,b,c,d什么的,实际上他们只用了128个,其中031是控制字符,32127是可显示字符,这就是后来的ascii编码了:

但是啊,这些老美万万没想到,计算机是如此的受人欢迎,很快计算机就在
其它国家流行开了,其它国家看有很多本土常用的字符,ascii中没有,于是就有人想啊,一个字节中不是才用了一半吗,这不最高位还没用吗,于是各个国家就开始用最高位来扩展这个ascii以便能够表示自己国家的一些字符,但是这并不是对每个国家都有效的,特别是我们的大天朝,你英文就那几个,但是我们文化博大精深啊,我们的汉字那可就有好几万个,你就给我一个字节,我怎么玩?

gb2312、big-5与gbk

一个字节要表示我国那么多中文,是万万办不到的,那么就只好再加一个字节了:
我们不客气地把那些127号之后的奇异符号们直接取消掉, 规 定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前 面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样 我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、 日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的 编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。 中国人民看到这样很不错,于是就把这种汉字方案叫做 “GB2312”。GB2312 是对 ASCII 的中文扩 展。 但是,你以为这样就够用了吗?当然不行,gb2312能够表示很多简体汉字,但是繁体怎么办呢?台湾群众很不满啊,于是也自己搞了一套编码,于是big-5诞生了,你以为这样就完了?gb2312仅仅可以表示6000多个常用汉字你让其它不常用的怎么办?于是扩展呗,把之前gb2312中没有利用的位好好利用起来,就成了gbk,这又增加了20000多个汉字,但是咱们少数名族也要用电脑啊,于是有了后来的 GB18030

GB2312和GBK都是用两个字节来编码的,就算用完所有的位(256*256=65536)也不够为所有的汉字 编码。于是就有了目前最新的GB18030,它采用类似UTF-8的编码方式进行编码(每个字符的编码可以是 1、2或4个字节),拥有上百万个编码空间,足以支持中日韩三国所有汉字,并且还可以支持国内少数民族 的文字。

但是这毕竟是属于一种“方言”式的编码,很多其它国家是不懂你这个编码的,于是各种编码的出现又导致了混乱,于是unicode闪亮登场了!

unicode与utf-8

在这之前我们需要先理清个概念:
Unicode只是简单的字符到数字的一个映射,就相当于一个电话本,它是没有字节限制的,是可以无限表示的,它也不管一个字符在计算机中式怎么存储的,具体怎么存储涉及到字符编码,而unicode应该叫做字符集
Unicode为世界上的每一个字符都弄了一个对应的数字,所以就不会再存在乱码问题了,比如,汉字 严 的 Unicode 是十六进制数 4E25 ,转换成二进制数足足有15位( 100111000100101 ),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号, 可能需要3个字节或者4个字节,甚至更多,这里会出现几个问题:
**A.**我们怎么知道是三个字节一起表示一个字符,还是说三个字节分别表示三个字符
**B.**之前一个ascii字符只需要一个字节,但是现在用了unicode普遍使用三个或四个字节,那使用英文就回浪费很多字节
于是针对unicode出现了很多不通的编码方案,这些方案就是为了解决unicode再计算机中具体怎么存储的问题,经常听说的有:utf-8、utf-16、utf-32
utf-16是用两个或四个字节表示一个字符
utf-32使用四个字节表示一个字符
而utf-8是可变长的编码方案,它可以用1~4个字节表示不同字符,显而易见,前面两种编码方案会浪费很多字节,而utf-8就很好了,所以我们现在也通常使用utf-8。
那utf-8具体是怎么编码unicode的呢?
1)对于单字节的符号,字节的第一位设为 0 ,后面7位为这个符号的 Unicode 码。因此对于 英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于 n 字节的符号( n > 1 ),第一个字节的前 n 位都设为 1 ,第 n + 1 位设为 0 ,后面字节的前两位一律设为 10 。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
根据utf-8的编码规则,我们就可以发现它很好的解决了前面的两个问题:
兼容ascii且不适用多余的字节,多字节的字符,我们可以通过判断它的第一个字符来确定字节数。
这是一份编码表,其中xxx处填写相应的unicode值

举个例子:
“侠”的unicode表示是4fa0,根据上表我们来计算一下它的utf-8编码:
根据上表,4fa0在第三行的位置,也就是我们需要把unicode值依次填入1110xxxx 10xxxxxx 10xxxxxx中,开始填字游戏吧:
11100100 10111110 10100000
转换为16进制后:E4BEA0
####ansi又是什么?
其实ANSI并不是某一种特定的字符编码,而是在不同的系统中,ANSI表示不同的编码。你 的美国同事Bob的系统中ANSI编码其实是ASCII编码(ASCII编码不能表示汉字,所以汉字为乱码),而你 的系统中(“汉字”正常显示)ANSI编码其实是GBK编码,而韩文系统中(“한국어”正常显示)ANSI编码其 实是EUC-KR编码。
windows系统通过Windows code pages的值来确定当前系统的编码方式。

现在我们就可以来看一下联通干不过移动的原因了,因为我们在记事本中不指定存储编码时默认时ansi,在中国的电脑上也就是gbk编码,而联通的gbk编码是:
c1 1100 0001
aa 1010 1010
cd 1100 1101
a8 1010 1000
有没有发现它和utf-8有点像?没错,它就是与utf-8编码冲突了,在我们第二次打开记事本的时候,记事本误以为它是utf-8编码。于是就按照utf-8的格式解析了,我们去掉模板后,再补上前导0:00000000 01101010
转为16进制:006A
对应unicode是小写字符j

但是后一个字节用同样的方法后是:0368不能表示任何字符,所以记事本机会乱码了。

参考资料

ansi是什么编码:http://www.cnblogs.com/malecrab/p/5300486.html

阮一峰的解释:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

中文字符的几种编码:http://www.cnblogs.com/malecrab/p/5300497.html

细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4 :
http://www.cnblogs.com/malecrab/p/5300503.html

国外比较好的一篇文章(推荐):https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

海纳百川

unicode、utf-8、ansi、gbk、gb2312编码详解相关推荐

  1. ASCII 、GB2312、GBK、GB18030、unicode、UTF-8字符集编码详解 1

    ASCII字符集编码     ASCII码是7位编码,编码范围是0x00-0x7F.ASCII字符集包括英文字母.阿拉伯数字和标点符号等字符.其中0x00-0x20和0x7F共33个控制字符.     ...

  2. 字符集编码详解【ASCII 、GB2312、GBK、GB18030、unicode、UTF-8】(转)

    ASCII字符集编码 ASCII码是7位编码,编码范围是0x00-0x7F.ASCII字符集包括英文字母.阿拉伯数字和标点符号等字符.其中0x00-0x20和0x7F共33个控制字符. 只支持ASCI ...

  3. ASCII 、GB2312、GBK、GB18030、unicode、UTF-8字符集编码详解

    ASCII码表在线查询: http://www.weste.net/tools/ASCII.asp ASCII字符集编码 ASCII码是7位编码,字符在计算机中以其ASCII码方式表示,其长度为1个字 ...

  4. ASCII 、GB2312、GBK、GB18030、unicode、UTF-8字符集编码详解(转载)

    ASCII字符集编码 ASCII码是7位编码,字符在计算机中以其ASCII码方式表示,其长度为1个字节, 有符号字符型数.编码范围是0x00-0x7F(0~127).ASCII字符集包括英文字母.阿拉 ...

  5. 字符编码详解及由来(UNICODE,UTF-8,GBK)

    字符编码详解及由来(UNICODE,UTF-8,GBK) 各种字符编码方式详解及由来(ANSI,UNICODE,UTF-8,GB2312,GBK) - 2009-01-29 09:53     一直对 ...

  6. unicode编码详解_转载

    unicode编码详解,一看就懂  转载--https://www.cnblogs.com/hahlzj/p/11908713.html 一.Unicode编码 1 UTF-8 -16 -32编码和U ...

  7. 嵌入式汉字显示原理及GBK编码详解

    嵌入式汉字显示原理及GBK编码详解 ~~~~~~~~        关于各个编码的介绍和转换可以看我的另一篇博客:[C语言实现]十六进制面值转字符串.字符面值转十六进制.UNICODE与GBK互转,U ...

  8. Unicode编码详解(二):编码预备知识

    Unicode编码详解(二):编码预备知识 本文为原创文章,转载请注明出处,或注明转载自"黄邦勇帅(原名:黄勇) 本文是对<C++语法详解>一书相关章节的增补,以增强读者对字符的 ...

  9. Unicode编码详解(三):UTF-8编码

    Unicode编码详解(三):UTF-8编码 本文为原创文章,转载请注明出处,或注明转载自"黄邦勇帅(原名:黄勇) 本文是对<C++语法详解>一书相关章节的增补,以增强读者对字符 ...

最新文章

  1. Android test---robotium----简单例子
  2. ES6 使用数据类型Set求交集、并集、差集
  3. 白话详细解读(五)-----U-Net
  4. 9.OD-断点、命令
  5. 【目标检测_keypoint based 方法系列】基于关键点的目标检测
  6. 电信无线网服务器是什么,怎样使用路由器共享电信天翼无线网络
  7. 在Vmware下linux与ARM开发板的NFS系统搭建【ZT】
  8. 518. 零钱兑换 II(JavaScript)
  9. Jenkins_第五关_系统管理(1)
  10. [poj3252]Round Numbers_数位dp
  11. VS2012下MFC程序的换肤(Skin++、SkinMagic、USkin、SkinSharp)
  12. linux latex编译器,在Ubuntu系统中下载安装LaTeX编辑器TeXstudio的方法
  13. 福师电子计算机主要以,福师《计算机应用基础》在线作业一 电子计算机主要以划分发展阶段...
  14. 2017年值得一看的7个APP设计
  15. [c语言]在程序中检测键盘按键
  16. 一种结合基于股债利差的A股估值百分位、有限价值策略定投和股债组合投资的创新型低回撤高收益稳健理财方法
  17. 路径规划学习之地图生成(二)
  18. 年月日时的天干推算方法
  19. 研究生做java如何发论文_研究生毕业论文怎么发表
  20. 太阳神电商业务辅助工具1.5

热门文章

  1. dhu oj 题目列表
  2. FINWEX MDUKEY专题AMA精彩回顾
  3. Spring Boot 中如何统一 API 接口响应格式?
  4. 哪些地方可以打印试卷
  5. ShareSDK的使用
  6. 英伟达收购Arm计划落空,跨国半导体并购难再现?|硅基世界
  7. isis宣告网络_isis简要原理、实验和常用命令
  8. 2021年中国体外诊断(IVDs)市场趋势报告、技术动态创新及2027年市场预测
  9. python中可以终结一个循环的保留字是_以下可以终结一个循环的保留字是
  10. 使用Vue3+Element Plus开发Chrome插件