【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

前言

本文起因于一次我使用WPS的表格另存为功能导出为TXT文本,如下图所示:

WPS 提示保存的文本文件的类型为 Unicode ,事实上这句提示很废话。

因为众所周知,Unicode 只是一套编码标准,而不是具体的编码实现,简而言之只是提供了二进制与具体字符之间的对应关系。相信在实际开发中应该没有人在程序中指定编码格式为 Unicode 吧。

我在第一次读取导出的 txt 文件时是尝试的 utf-8 编码,代码如下:

const fs = require('fs')
fs.readFile('文本.txt',{encoding: 'utf8'},(err, data) => {
console.log(data)
})

没想到打印输出的全是乱码,没事,换个编码方式再尝试下。

fs 模块支持的编码方式包括 utf8、ucs2、ascii、binary、base64、hex。除了utf8 之外,属于 Unicode 编码标准的就是 ucs2 了,换成 ucs2 之后果然得到了正确的输出文字。

问题来了,utf8 和 ucs2 的区别是什么呢?别急,等我慢慢道来。

ASCII编码

先来了解一下编码的“祖宗” ASCII(American Standard Code for Information Interchange)即美国信息交换标准代码。它主要用于显示现代英语,包含了阿拉伯数字、大小写英文字母以及一些常用英式标点符号等。

简单来说,ASCII 编码使用 8 位共 1 字节的二进制数表示字符,范围从 0000 0000 到 0111 1111,可以表示 128 个字符。

Unicode 字符集中对这 128 个字符的编码与 ASCII 是一致的。

UTF-8编码

根据笔者在维基百科上的学习所得,utf-8 是一种针对 Unicode 的可变长度字符编码,也是一种前缀码。它可以用一至四个字节对Unicode字符集中的所有有效编码点进行编码,属于 Unicode 标准的一部分。

UTF-8 编码的规则还可以用下表所表示:

字节数 二进制
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

因此,对 UTF-8 编码中的任意字节,根据第一位是否为 0,可判断是否为 ASCII 字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节;根据前四位(如果前两位均为 1 ),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为 1 ),可判断编码是否有错误或数据传输过程中是否有错误。

UTF-16编码

【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

看下维基百科的专业解释:

UTF-16 是 Unicode 字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为"storage format")的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。

虽然有些晦涩难懂,但我们依旧可以得出,UTF-16 编码实现只支持通过 2 字节或者 4 字节去表示 Unicode 字符;也可以得出 UTF-16 编码实现不兼容 ASCII 编码(ASCII编码使用 1 字节来进行存储)。

UCS-2编码

我在维基百科的学习中,看到 UCS-2 词条放在了 UTF-16 词条文章下方,并有写明 UTF-16 可看成是 UCS-2 的父集。这是为什么呢?

如果把 UTF-16 支持的 Unicode 字符范围分为两块,即如下表所示:

Unicode范围 UTF-16编码方式
U+000~U+FFFF 2 Byte存储
U+10000~U+10FFFF 4 Byte存储

UTF-16 编码实现和 UCS-2 编码实现的区别就在于 UCS-2 只支持 UTF-16 编码中对U+000~U+FFFF范围内的Unicode字符。

对于小于 0x10000 的 UCS 码,UTF-16 编码就等于UCS码。现在如果有软件声称自己支持 UCS-2 编码,那其实是在说它不能支持在 UTF-16 中超过 2 字节的字集。

后记

到此,我们终于搞明白了 UTF-8 和 UCS-2 编码方式的区别,明白了他们虽同属于 Unicode 编码标准实现体系的一部分,但实际对 Unicode 字符编码的实现完全不同。以后,如果再看到存储为 Unicode 文本,你可以尝试下以 UCS-2 格式进行解码,相信大部分情况下都是行得通的。

忽略历史原因,只用下面这一张图就足够解释 Unicode 字符集的编码问题:

最后提供一个查看 Unicode 字符与编码的网站 Unicode字符百科

版权声明

【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

终于搞明白Unicode,ASCII,UTF8,UCS2编码是啥了的更多相关文章

  1. vue-router 路由元信息 终于搞明白了路由元信息是个啥了

    vue-router 路由元信息:https://blog.csdn.net/wenyun_kang/article/details/70987840 终于搞明白了路由元信息是个啥了:https:// ...

  2. ASCII,Unicode和UTF-8字符编码

    ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte).也就是 ...

  3. ASCII、Unicode、UTF-8字符集编码

    ASCII码 计算机内部,所有信息都是由二进制的字符串表示 每一个二进制位有“0”.“1”两种状态,因此8个二进制位可以表示256个状态,每个状态代表一个符号就是256个符号,从0000000到111 ...

  4. unicode ansi utf-8 unicode_big_endian编码的区别

      随便说说字符集和编码  快下班时,爱问问题的小朋友Nico又问了一个问题:  "sqlserver里面有char和nchar,那个n据说是指unicode的数据,这个是什么意思.&quo ...

  5. unicode 和 utf-8字符编码的区别

    作者:于洋链接:https://www.zhihu.com/question/23374078/answer/69732605来源:知乎著作权归作者所有,转载请联系作者获得授权.   原文:unico ...

  6. unicode 和utf-8,GBK编码

    说到编码,得先从ASCII编码讲起.ASCII编码是由美国人发明,美国的字符不超过255个,所以ASCII编码使用了8bit 即一个字节来存储字符.由于汉字的数量远超255个,所以中国自己发明了一个G ...

  7. 3-7 彻底搞清楚unicode和utf8编码

  8. 深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!

    英文:https://arpitbhayani.me/blogs/string-interning 作者:arpit 译者:豌豆花下猫("Python猫"公众号作者) 声明:本翻译 ...

  9. Windows下ANSI、Unicode、UTF8字符编码转换

    主意:输入字符串必须是以'\0'结尾,如果输入字符串没有以'\0'结尾,请手动设置,否则转换会有错误. unsigned int EncodeUtil::AnsiToUcs2( char* pAnsi ...

随机推荐

  1. 二刷Redux笔记

    关于react的一些思考 所有的数据全部先要发送给容器,然后容器负责接受数据单后再分发数据给他下面的组件,通过props来传递,一个页面就可以相当于一个容器,容器之中就会有很多子组件,一般组件只负责接 ...

  2. [PHP自动化-进阶]004.Snoopy VS CURL 模拟Discuz.net登陆

    引言:采集论坛第一步就是要模拟登陆,由于各个站点登录表单各不相同,验证方式又是多种多样,所以直接提交用户名密码到登录页面就比较繁琐. 所以我们采用cookie来模拟登陆无疑是最佳捷径. 今天我们要处理 ...

  3. RabbitMQ镜像集群搭建

    RabbitMQ 官网 https://www.rabbitmq.com/ 小编使用的系统环境是CentOS7.4 系统 IP hostname CentOS7.4 1.1.1.1 hostname0 ...

  4. NodeJS——在Sublime中配置NodeJS执行环境

    这种方式比在DOS窗中直接执行更加高效!!! nodejs 1.运行Sublime,菜单上找到Tools ---> Build System ---> new Build System 2 ...

  5. 关于hexo中plugins博客配置对无法生成index.html文件的影响

    用hexo搭建的博客网站在访问时出现403错误,经调查后发现是public文件夹下的index.html文件丢失. 在csdn上搜了一下发现大家都是查看是否有一下hexo的插件未安装,将未安装插件安装 ...

  6. SRAM电路工作原理

    近年来,片上存储器发展迅速,根据国际半导体技术路线图(ITRS),随着超深亚微米制造工艺的成熟和纳米工艺的发展,晶体管特征尺寸进一步缩小,半导体存储器在片上存储器上所占的面积比例也越来越高.接下来宇芯 ...

  7. Cypress系列(6)- Cypress 的重试机制

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 重试(Retry-ability) ...

  8. Rocket - decode - Simplify

    https://mp.weixin.qq.com/s/YWXYNaRU-DbLOMxpzF2bpQ   介绍Simplify如何简化解码逻辑.     1. 使用   Simplify在DecodeL ...

  9. JavaSE (六)面向对象 -- 类的结构

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 目录 一.属性(变量) 1.变量的分类: 二.方法 1.例子: 2.格式: 3.方法的说明: 4.ret ...

  10. Java并发编程 (二) 并发基础

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.CPU多级缓存-缓存一致性 1.CPU多级缓存 ​ 上图展示的是CPU高级缓存的配置,数据的读取和存 ...