简述字符集与编码

因为计算机内部只能识别和处理二进制代码,因此字符都必须按照必定的规则用一组二进制编码来表示。html

在学习编码以前,须要先了解一下 字符集与编码的关系:
字符集(Character Set)是字符的集合,定义系统能处理哪些字符;编码(Encoding)则规定这些字符在计算机内部的表示方式。web

image

字符编码ASCII码(编码字符集)

目前,国际上广泛采用的一种字符系统是7位二进制编码的ASCII码,它可表示10个十进制数码、52 个英文大写字母和小写字母(A~Z, a~z)及必定数量的专用符号(如$、%、+、=等),共128个字符。为了存入计算机,一般最高位补0,凑足1B。数据库

在ASCII码中,编码值0~31为控制字符,用于通讯控制或设备的功能控制;编码值32~126共95个字符称为可印刷字符;编码值127是DEL码。浏览器

0~9的ASCII码值为48(0110000)~57(0111001),即去掉高3位,只保留低4位,正好是二进制形式的0-9。

因为ASCII码的局限性,各国的语言不能完整地表示出来。因而对 ASCII 字符集作了拓展。服务器


汉字的表示和编码

目前采用 GB 2312-80标准 : 汉字+各类符号共7445个。用两个字节表示一个汉字,每字节用七位码。(1个汉字至关于两个英文字符)app

规定:ASCII 值小于 127 的字符的意义与原来 ASCII 集中的字符相同,但当两个 ASCII 值大于 127 的字符连在一块儿时,就表示一个简体中文的汉字。svg

为了在解码时操做的统一,在 ASCII 里原本就有的数字、标点、字母都统一从新表示为了两个字节长的编码,这就是常说的 “全角” 字符,而原来在 127 号如下的就叫 “半角” 字符。工具

汉字编码包括:

  • 输入编码学习

    • 区位码
    • 国标码
  • 汉字内码
  • 汉字字形码

区位码:94个区,每区94个位置。是4位十进制数,前2位是区码,后2位是位码。
国标码:将十进制的区位码转换成十六进制数后,再在每字节上加上20H。国标码两字节的最高位都是0。
汉字内码:为了方便计算机区分中文字符和英文字符,将国标码两字节最高位都改成“1“,这就是汉字内码。编码

GBK

GBK 是对 GB2312 的一个扩展,兼容 GB2312,所以也兼容 ASCII,也是一个变长编码方案。下面是一个简介:

GBK 整体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。

GBK 是国家有关部门与一些信息行业企业等一块儿合做推出的方案,但并未做为国家标准发布,只是一个事实上的标准,一个过渡方案,为 GB18030 标准做的一个准备。


世界上各国都有不一样的编码方式,0—127 表示的符号依然都是同样的,由于他们都兼容 ASCII 码,但127以后的同一个二进制数字能够被解码成不一样的符号。所以,要想打开一个文本文件,就必须知道它的编码方式,不然用错误的编码方式解读,就会出现乱码。


Unicode

把全部语言都统一到一套编码里,且兼容 ASCII。

ASCII、GBK 等类编码模式的字符集和编码方式都是一一对应的,Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三种字符编码方案。

整个编码可分为两个过程。首先,将程序中的字符根据字符集中的编号数字化为某个特定的数值,而后根据编号以特定的方式存储到计算机中。

编号就至关于 ASCII 码中的 ASCII 值,它就是 Unicode 字符集中惟一表示某个字符的标识,在 Unicode 也称做码点(Code Point)

image

码点转换成各类编码,又涉及到编码过程当中定长变长两种实现方式,UTF-32 就属于定长编码,即永远用 4 字节存储码点,而 UTF-八、UTF-16 就属于变长存储,UTF-8 根据不一样的状况使用 1-4 字节,而 UTF-16 使用 2 或 4 字节来存储码点。

UTF-32

在 UTF-32 这种定长的编码方式下就表示每 4 个子节一个断句,那么字符 A 的码点 U+0041(二进制为 1000001)被 UTF-32 编码后就会变成以下形式存储在计算机中:

00000000 00000000 00000000 01000001

它会将 4 个字节中空出的高位所有填充为 0。这种表示的最大缺点是占用空间太大,由于无论都大的码点都须要四个字节来存储,很是的占空间,那么如何突破这个瓶颈呢?变长方案应运而生。

UTF-8

UTF-8 属于变长的编码方式,它可使用1~4个字节表示一个符号,根据不一样的符号而变化字节长度。使用的是高位保留的方式来区别不一样变长,具体方式以下:

  1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。所以对于英语字母,UTF-8 编码和 ASCII 码是相同的。
  2. 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一概设为10。剩下的没有说起的二进制位,所有为这个符号的 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

解码 UTF-8 编码也很简单了,若是一个字节的第一位是 0,则这个字节单独就是一个字符;若是第一位是1,则连续有多少个 1,就表示当前字符占用多少个字节,”丑” 有三个 1 表示占三个字符,而后取出有效位便可。

Emoji

Unicode 为 Emoji 分配码点。 Emoji 符号就是一个文字,它会被渲染为图形。

Emoji编码


以上三种都是属于文字的编码,但在计算机中,还有相似图片这种媒体资源。由于图片的二进制编码中包含有不少不可见字符,没法用文本展现。


Base64

base64编码是用来解决把不可打印的内容塞进可打印内容的需求的。好比把图片存到数据库,图片数据归根到底仍是一堆二进制串,用base64编码后的显示成的字符串就大大缩小的长度,能够存到数据库。

所谓Base64,就是:小写字母a-z、大写字母A-Z、数字0-九、符号"+"、"/"(再加上做为垫字的"=",其实是65个字符)----做为一个基本字符集。而后,其余全部符号都转换成这个字符集中的字符。

具体来讲,转换方式能够分为四步。

第一步,将每三个字节做为一组,一共是24个二进制位。
第二步,将这24个二进制位分为四组,每一个组有6个二进制位。
第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。
第四步,根据下表,获得扩展后的每一个字节的对应符号,这就是Base64的编码值。

由于,Base64将三个字节转化成四个字节,所以Base64编码后的文本,会比原文本大出三分之一左右。

若是字节数不足三,则这样处理:

1.二个字节的状况:将这二个字节的一共16个二进制位,按照上面的规则,转成三组,最后一组除了前面加两个0之外,后面也要加两个0。这样获得一个三位的Base64编码,再在末尾补上一个"="号。

好比,"Ma"这个字符串是两个字节,能够转化成三组000100十一、000101十、00010000之后,对应Base64值分别为T、W、E,再补上一个"="号,所以"Ma"的Base64编码就是TWE=。

2.一个字节的状况:将这一个字节的8个二进制位,按照上面的规则转成二组,最后一组除了前面加二个0之外,后面再加4个0。这样获得一个二位的Base64编码,再在末尾补上两个"="号。

好比,"M"这个字母是一个字节,能够转化为二组000100十一、00010000,对应的Base64值分别为T、Q,再补上二个"="号,所以"M"的Base64编码就是TQ==。

转换Base64工具
参考文章

计算机中通用的字符编码的工做方式

在计算机内存中,统一使用Unicode编码,当须要保存到硬盘或者须要传输的时候,就转换为UTF-8编码。

浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。

Web 中的编码

要正确显示HTML页面,web浏览器必须知道页面中使用的字符集。

<!-- html -->
<meta charset="UTF-8">
​
<!-- xml -->
<?xml version="1.0" encoding="UTF-8"?>

比较HTML和xml中的写法:xml的写法更加规范

  • charset 是 character set 的简写,即字符集
  • encoding 是 charset encoding 的简写,即字符集编码,简称编码

指定了编码,它所对应的字符集天然就指定了,编码才是咱们最终要关心的。

如何肯定一个网页中编码

  1. 文档内的编码声明

    image

  2. 响应体中的content-type字段中的编码信息

    image

  3. BOM

    BOM=Byte Order Mark,“字节顺序标识”。响应流中的开头字节。

    若是有 BOM,就能直接知道对应的编码

    img

  4. 缺省

    缺省方式是以上几种方式都失效时的兜底方案,没有 BOM,没有 header,没有 meta,浏览器只好“蒙”一个编码。

若是多方式并存,且给出的编码信息不一致,一般按这样的优先级来取舍:

BOM > 响应头编码 > 文档内编码声明

HTML 编码

在 HTML 中,某些字符是预留的,好比不能使用小于号(<)和大于号(>),这是由于浏览器会误认为它们是标签。若是但愿正确地显示预留字符,咱们必须在 HTML 源代码中使用字符实体(character entities)。

字符实体: // <
​
& entity_name; // &lt;
或
& entity_number; // &#60;

URI 编码

编码缘由:

考虑到 URI 在各类平台间传输时的兼容性,URI 规范中规定只有 US-ASCII 字符集中的字符能够直接出如今 URI 中。事实上,甚至 ASCII 自己的许多字符也不容许直接出如今 URI 中,有的也要转义。URL 路径中的中文须要转义,具体编码用的是 utf-8。

能够直接使用的: 26 个大小写字母,10 个数字,四个标点符号:-._~(“短横”、“点号”、“下划线”、“波浪线”)。其它的有的属于保留字,用做为分隔符(delimiters),它们有:

":" / "/" / "?" / "#" / "[" / "]" / "@" / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

好比正斜杠“/”就是一个最经常使用的分隔符。若是想在 URL 中包含这样符号,又不想它们被解析为分隔符,就要对其转义。其它的还有一些不能够打印的字符也要转义,好比“空格”等。

保留字符在不作分隔符或者具备特殊含义的时候是须要编码的。若是使用了一些其余文字和特殊字符,则须要经过编码的方式来进行表示:

%编码

因为 URI 在协议中只挑选了部分ASCII 字符,数字以及符号,那么当须要表示不在这个范围以内的符号,字符,或者该字符在 URI 中被用来分隔符等特殊用途时,就须要对这个字符进行%编码。百分号编码也能够叫作URLEncode,其中的每个部分用【%XX】来表示,其中 XX 表示一个十六进制的数。

encodeURI 会将须要编码的字符转换为 UTF-8 的格式。对于非转义字符以及保留字符(;,/?:@&=+$#)不会进行转义。

// URL中包含中文
encodeURI('http://www.帅.com'); // http://www.%E5%B8%85.com
​
// 值的内容为特殊符号。值为?&
encodeURI('http://a.com?key=?&'); // "http://a.com?key=?&"

encodeURIComponent 会编码全部的 URL 保留字:

encodeURIComponent('https://aotu.io/')
// "https%3A%2F%2Faotu.io%2F"
​
encodeURI('https://aotu.io/')
// "https://aotu.io/"

在处理页面跳转、跟服务器端进行交互时, 凡涉及到对URI进行解析的、最好用encodeURIComponent进行编码避免部分数据的丢失.

相关文章
相关标签/搜索