ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清

前言

Github上下载了一份代码打算学习,源工程是在linux上开发的,我在Windows上编译通过不了,很多莫名奇妙的错误,最后发现源代码文件是UTF-8(without BOM)编码的,Notepad++修改编码格式为UTF-8编译通过。

  1. 为什么Windows不认识UTF-8(without BOM)?
  2. 为什么Linux认识UTF-8(without BOM)和UTF-8?

ASCII

毕竟在电子系混过四年,这个词不陌生,用一个字节的低7位来表示128个英文字符(0xxxxxxx),可是地球上的文字又不是只有英文,光汉字就好几万个,所以每个国家和地区又做了一套符合自身情况的编码规范,比如简体中文编码标准GB2312,使用两个字节来表示一个汉字,可以表示65536个中文字符。但是如果每个国家都这么搞那不就乱套了嘛,于是Unicode就应运而生了。

Unicode

Unicode是个符号集,与ASCII类似,只不过容量要大得多,可以理解成一张表,为世界上的每一个字符指定了一个惟一的二进制代码,但是它并没有规定这个二进制代码如何存储,于是乎UTF-8、UTF-8(without bom)、UTF-16、UTF-32应运而生。

UTF

  • UTF(Unicode Transformation Format)意为把Unicode字符转换成某种格式,常见到的有:

  • UTF-8:使用1至4个字节为每个字符进行编码,节省空间。

  • UTF-16:使2或4个字节为每个字符编码,大多数汉字采用2个字节,少了生僻字使用4个字节,编码单元为2个字节,所以存在字节序的问题,即大端还是小端。(不常用)

  • UTF-32:使4个字节为每个字符编码,编码单元为4个字节,所以存在字节序的问题,即大端还是小端。(不常用)

UTF-8

UTF-8是Unicode的实现方式之一,最大特点就是根据符号自动变化字节长度,即可变长编码,编码方式如下图所示:

	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
  • 对于单字节字符,第一位为0,后面7位位对应的Unicode码,显然UTF-8是兼容ASCII的,

  • 对于n(n > 1)字节字符,第一个字节的前n位都设为1,第 n+1位设为0,后面的n-1个字节前两位一律设为10,其余的字节(图上的x)即为Unicode码。

UTF-8(without BOM)

BOM(Byte Order Mark)字节顺序标记,即可以用来标记是大端还是小端。在Unicode里面定义了一个叫做

”ZERO WITH NO-BREAK SPACE“的不可见字符,对应的Unicode编码是FEFF,有BOM的文件即文件开头有”ZERO WITH NO-BREAK SPACE“不可见字符,反之则没有。若是大端编码,则文件开头是FEFF,小端则是FFFE。BOM是为了配合UTF-16和UTF-32使用,因为它们编码编码单元包含多个字节,涉及字节序的问题。

UTF-8以单字节为编码单元,不存在字节序的问题,但是可以使用BOM来表明所使用的编码方式,字符”ZERO WITH NO-BREAK SPACE“在UTF-8中的编码是EF BB BF,所以当解码文件时发现开头的单个字节是EF BB BF即说明是UTF-8编码,Windows就是使用BOM来标记文本的编码方式的。

怎样区分UTF-8、UTF-16和UTF-32

打开文本时根据BOM来区分当前文件的编码类型

BOM							编码类型
——————————————————————————————————————
EF BB BF UTF-8
FE FF UTF-16(大端)
FF FE UTF-16(小端)
00 00 FE FF UTF-32(大端)
FF FE 00 00 UTF-32(小端)

最新文章

  1. YACC和BISON学习心得
  2. Vue基础---->VueJS的使用(二)
  3. getBoundingClientRect() 来获取页面元素的位置
  4. OleDbType.Decimal在插入DB2后会默认赋值0.00,改为OleDbType.Double则正常
  5. C#中怎么在EXCEL中的单元格中画斜线啊 ??
  6. Ubuntu 12.04搭建Andorid编译环境
  7. 如何取消Linux下,vi中显示的^M符号
  8. 超链接字体颜色设置(通过html/css的设置方法)
  9. 【转】中兴G718C卡刷刷机教程(青漾2 4G)--不错
  10. 【动态规划】【二分】【最长上升子序列】Vijos P1028 魔族密码
  11. Jump Game 解答
  12. Unix环境下PS1变量的设置
  13. java抽象类、抽象方法、接口、实现接口详解
  14. 浏览器正确理解和使用GBK及UTF-8(UTF-8 + BOM)网页编码
  15. Epemme
  16. QVM 实操记 - 18.12.28
  17. kill -9 ,kill -12,kill -15
  18. Vue源码学习(二)$mount() 后的做的事(1)
  19. pip 指定版本
  20. Sangfor_AC用户不在线但在“在线用户管理”里有显示

热门文章

  1. 云服务器、euleros系统自动断开连接解决方案
  2. C++字符串操作小结
  3. Vagrant系列(一)----win10搭建Vagrant+VirtualBox环境_
  4. rabbitmq 交换机模式一 直连模式 direct
  5. Mac安装stf
  6. Flink on Yarn三部曲之二:部署和设置
  7. Codeforces Round 662 赛后解题报告(A-E2)
  8. codeforces #271D Good Substrings
  9. React.Component 和 React.PureComponent 、React.memo 的区别
  10. python坐标获取经纬度或经纬度获取坐标免费模块--geopy