ASCII、Unicode、utf-8、utf-16、utf-32
理解ASCII、Unicode、utf-8、utf-16、utf-32
理解ASCII、Unicode、utf-8、utf-16、utf-32编码与解码字符集字符编码ASCIIUnicodeUTFUTF-32UTF-16UTF-8UTF-8的编码实现方法Emoji问题
编码与解码
在计算机中,信息是由 0和1组成的二进制 进行传递的,将我们看到的字符转化为二进制数字的过程就是编码,反之将二进制数字转换为字符的过程是解码。
字符集
ASCII和Unicode分别是两种不同的编码方式,通过某一种编码方式进行编码所组成的集合称为字符集。如,字符通过Unicode编码所组成集合称为Unicode字符集。
字符编码
对于一个字符集来说要正确编码转码一个字符需要三个关键元素:字库表(character repertoire)、编码字符集(coded character set)、字符编码(character encoding form)。
字库表,决定了整个字符集能够展现表示的所有字符的范围。
编码字符集,即用一个编码值来表示一个字符在字库中的位置。如Unicode。
字符编码,将编码字符集和实际存储数值之间的转换关系。一般会将编码字符集的值作为编码后的值直接存储。如UTF-8。
看到这里,可能很多读者都会有和我当初一样的疑问:
字库表和编码字符集看来是必不可少的,那既然字库表中的每一个字符都有一个自己的序号,直接把序号作为存储内容就好了。为什么还要多此一举通过字符编码把序号转换成另外一种存储格式呢?其实原因也比较容易理解:统一字库表的目的是为了能够涵盖世界上所有的字符,但实际使用过程中会发现真正用的上的字符相对整个字库表来说比例非常低。例如中文地区的程序几乎不会需要日语字符,而一些英语国家甚至简单的ASCII字库表就能满足基本需求。而如果把每个字符都用字库表中的序号来存储的话,每个字符就需要3个字节(这里以Unicode字库为例),这样对于原本用仅占一个字符的ASCII编码的英语地区国家显然是一个额外成本(存储体积是原来的三倍)。算的直接一些,同样一块硬盘,用ASCII可以存1500篇文章,而用3字节Unicode序号存储只能存500篇。于是就出现了UTF-8这样的变长编码。在UTF-8编码中原本只需要一个字节的ASCII字符,仍然只占一个字节。而像中文及日语这样的复杂字符就需要2个到3个字节来存储。
ASCII
由于计算机是美国人发明的,并没有考虑其他国家的字符,最早的编码方式便是ASCII。0 - 255被用来表示大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码。
Unicode
Unicode编码定义了这个世界上几乎所有字符,而且Unicode还兼容了很多老版本的编码规范,例如刚刚讲过的 ASCII码。Unicode 编码 发展到今天 扩展到了 21 位。详见http://en.wikipedia.org/wiki/Unicode
Unicode也为了每个字符发了一张身份证,这张“身份证”上有一串唯一的数字ID确定了这个字符。这串数字在整个计算机的世界具有唯一性,Unicode给这串数字ID起了个名字叫 码点 。码点 经过映射后得到的二进制串的转换格式单位称之为 码元。码点就是一串二进制数,码元 就是切分这个二进制数的方法。
Unicode的编号从 0000开始一直到 10FFFF共分为16个Plane,每个Plane中有65536个字符(正好填充2个字节,16位)。0 号平面叫做基本多文种平面( BMP, Basic Multilingual Plane ),涵盖了几乎所有你能遇到的字符,除了 emoji(emoji位于1号平面 ),其它平面叫做补充平面,大多是空的。
UTF
Unicode转换格式(Unicode Transformation Formats,即UTF),是为了解决码点在计算机中存储方式而设计的。
UTF-32
UTF-32是最好理解的一个了。UTF-32也就是说它的码元是32位,每32位去读一下码点,而码点是Unicode给字符的编码,前面也说了,最长才21位,因此每一个 UTF-32 值都可以直接表示对应的码点。
UTF-16
UTF-16的码元是16位的,也就是说每16位去读一下码点,获取码点的前16位数字,直到读取完成。由于BMP 几乎包括了所有常见字符,UTF-16 一般需要 UTF-32大约 一半的空间。至于其它平面里很少使用的码点都是用两个 16 位的码元来编码的。
UTF-8
UTF-8 使用一到四个字节来编码一个码点。从 0 到 127 的这些码点直接映射成 1 个字节(对于只包含这个范围字符的文本来说,这一点使得 UTF-8 和 ASCII 完全相同)。接下来的 1,920 个码点映射成 2 个字节,在 BMP 里所有剩下的码点需要 3 个字节。Unicode 的其他平面里的码点则需要 4 个字节。UTF-8 是基于 8 位的码元的。UTF-8 是基于 8 位的码元的,因此它并不需要关心字节顺序(因为字节就是8位的呀,其它UTF-16和UTF-32在不同的机器编译环境下需要考虑字节的顺序问题)
UTF-8的编码实现方法
UTF-8编码为变长编码。最小编码单位为一个字节。一个字节的前1-3个bit为描述性部分,后面为实际序号部分。
如果一个字节的第一位为0,那么代表当前字符为单字节字符,占用一个字节的空间。0之后的所有部分代表在Unicode中的序号。
如果一个字节以110开头,那么代表当前字符为双字节字符,占用2个字节的空间。110之后的所有部分代表在Unicode中的序号。且第二个字节以10开头
如果一个字节以1110开头,那么代表当前字符为三字节字符,占用3个字节的空间。110之后的所有部分代表在Unicode中的序号。且第二、第三个字节以10开头
如果一个字节以10开头,那么代表当前字节为多字节字符的第二个字节。10之后的所有部分代表在Unicode中的序号。
具体每个字节的特征可见下表,其中 x代表序号部分,把各个字节中的所有 x部分拼接在一起就组成了在Unicode字库中的序号
| Byte1 | Byte2 | Byte3 |
|---|---|---|
| 0xxx xxxx | ||
| 110x xxxx | 10xx xxxx | |
| 1110 xxxx | 10xx xxxx | 10xx xxxx |
可以得出这样一个规律:
3个字节的UTF-8十六进制编码一定是以
E开头的2个字节的UTF-8十六进制编码一定是以
C或D开头的1个字节的UTF-8十六进制编码一定是以比
8小的数字开头的
Emoji问题
前面也提到Emoji位于1号平面,是需要四个字节来编码的,Emoji在Unicode中位于 \u1F601- \u1F64F区段。这个显然超过了目前常用的UTF-8字符集的编码范围 \u0000- \uFFFF。Emoji表情随着IOS的普及和微信的支持越来越常见。下面就是几个常见的Emoji:
ASCII、Unicode、utf-8、utf-16、utf-32的更多相关文章
- ASCII、UNICODE、UTF
在计算机中,一个字节对应8位,每位可以用0或1表示,因此一个字节可以表示256种情况. ascii 美国人用了一个字节中的后7位来表达他们常用的字符,最高位一直是0,这便是ascii码. 因此asci ...
- 【转】【编码】ASCII 、UNICODE和UTF-8之二
字符发展 1. 美国 ASCII-(American standard code information interchange) 美国信息互换标准代码 范围:1-127 ; 单字 备注:前部用作控制 ...
- ASCII、Unicode、GBK和UTF-8字符编码的区别联系(转载)
ASCII.Unicode.GBK和UTF-8字符编码的区别联系 转载自:http://dengo.org/archives/901 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同 ...
- 字符编码笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
转载:http://witmax.cn/character-encoding-notes.html 今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问 ...
- 字符编码终极笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
1.字符编码.内码,顺带介绍汉字编码 字符必须编码后才能被计算机处理.计算机使用的缺省编码方式就是计算机的内码.早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB231 ...
- 字符编码的种类:ASCII、GB2312、GBK、GB18030、Unicode、UTF-8、UTF-16、Base64
ASCII码ASCII:https://zh.wikipedia.org/wiki/ASCIIASCII(American Standard Code for Information Intercha ...
- 【转】字符编码笔记:ASCII、Unicode、UTF-8 和 Base64
1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态(-128~127),这被称为一 ...
- ASCII编码、Unicode编码、UTF-8
一.区别 ASCII.Unicode 是“字符集” UTF-8 .UTF-16.UTF-32 是“编码规则” 其中: 字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code ...
- 关于字符编码:ascii、unicode与utf-8
转自:https://foofish.net/unicode_utf-8.html 阮一峰老师对普及计算机基础技术功不可没,但毕竟老师不是神,因此也避免不了对某些概念有一些错误的理解,<字符编码 ...
- ANSI、ASCII、Unicode和UTF-8编码
来自:http://blog.163.com/yang_jianli/blog/static/161990006201371451851274/ --------------------------- ...
随机推荐
- selenium 定位 页面上两个完全一样的元素
在测试过程中发现页面上有两个保存按钮的元素的xpath一模一样,如下图: google了好久才找到解决办法,发现自己还是比较弱!!!解决方法如下: selenium.click("xpath ...
- JAVA并发-CountDownLatch
源码: 内部类Sync private static final class Sync extends AbstractQueuedSynchronizer { private static fina ...
- LG5200 「USACO2019JAN」Sleepy Cow Sorting 树状数组
\(\mathrm{Sleepy Cow Sorting}\) 问题描述 LG5200 题解 树状数组. 设\(c[i]\)代表\([1,i]\)中归位数. 显然最终的目的是将整个序列排序为一个上升序 ...
- 【oracle】11g服务器安装详细步骤
以下是百度经验:https://jingyan.baidu.com/article/363872eccfb9266e4aa16f5d.html 1.同时解压 2.setup 3.
- [LeetCode] 877. Stone Game 石子游戏
Alex and Lee play a game with piles of stones. There are an even number of piles arranged in a row, ...
- java ++前缀
public class Sample { public static void main(String[] args) { , num2 = ; , num4 = ; ++num1; System. ...
- nodejs调用cmd命令
使用 child_process.exec 实现 child_process即子进程可以创建一个系统子进程并执行shell命令,在与系统层面的交互上非常有用 NodeJS子进程提供了与系统交互的重要接 ...
- linux 三剑客(awk,sed,grep)
1.awk 在某些场景下,我们需要过滤方式希望是列来匹配,而不是sed的行来匹配,而且awk还可以嵌套for等循环去使用,拓展性强,当然awk也是最难的. awk的常用命令选项: -F fs fs ...
- visual studio -- 调试时自动传递给exe入参
如果你写的main函数接受入参int main(int argc, char* argv[]),则可以 右键工程--属性--调试,在命令行参数中输入入参即可,这些字符串会被直接传递给exe.
- 循环节 + 矩阵快速幂 - HDU 4291 A Short problem
A Short problem Problem's Link Mean: 给定一个n,求:g(g(g(n))) % 1000000007 其中:g(n) = 3g(n - 1) + g(n - 2), ...