字符编解码 5B57 7B26 7F16 89E3 7801

这里有字符编解码的基本知识、常见字符编解码工具以及各种编码的简介。


编码

{{item.title}}

{{item.code}}


{{encode_result.caption}}

{{encode_result.error}}

解码

{{item.title}}

{{item.code}}


{{decode_0_result.caption}}

{{decode_0_result.error}}

解码

{{item.title}}

{{item.code}}


{{decode_1_result.caption}}

{{decode_1_result.error}}

什么是编码?

编码可以指编写程序代码,不过这里我们说的编码指的是:表示信息的不同格式,以及这些格式之间的转换。编码存在以下几种情况:

  • 字符到二进制的编码,因为计算机处理的都是二进制数据,所以当我们要在计算机系统中表示一个字符时,我们必然需要将字符对应到一个二进制数值。 比如字符“Z”的 Latin-1 字符集的二进制编码为 “01011010”,为方便起见我们也可以用16进制表示为“5A”。 这里的“5A” 就是 “Z” 字符在 Latin-1 字符集下的编码。 Latin-1 是 ISO-8859-1 的别称,单字节编码,它兼容了 ASCII 码,并新增了字符。

  • 字符到字符的的编码,另有一种编码情况就是字符与字符之间的转换。这里我们以 JavaScript 里的encodeURI方法为例,由于我们不能在URL中传输非ASCII字符和保留字符。 我们就需要将这些字符进行编码,让ASCII字符来表示这些字符,如:空格用 %20 表示,“好” 用 %E5%A5%BD 来表示。 其实E5A5BD是好字的 UTF-8编码。

  • 二进制到字符的编码,有时候我们需要将二进制文件如图片表示在文本中,比如在Html直接保存图片信息,这时候我们就可以使用Base64编码将图片转换为字符串并以下面的方式设置到img标签上:
    <img src=“data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAA...” />

编码的表示与转义

上一段中讲到了字符“Z”的两种编码标识方式,二进制(01011010),16进制(5A),但是这两种表示的本身也是一段字符串,如果你在编程语言中直接为一个变量设置“01011010”或“5A”,编程语言会认为你设置的是字符本身而不会认为这是某个字符的编码。

要解决这个问题就要引入转义,所谓“转义”就是转变字符的含义,我们以 javascript 语言为例。在字符串中的转义符为反斜杠“\”,其中“\x”表示其后的中字符代表 Latin-1 编码,而“\u”代表其后的字符为 Unicode 编码。 你可以尝试在Chrom的控制台中输入 "\x5A" 返回就是字符“Z”

字符的转义

有的转义则是使用字符来表示一些不可打印字符或者是有特殊含义的字符,比如"\n"表示换行符,"\r"表示回车符;还有在HTML语言中我们使用 &nbsp; 来表示空格;在UrlEncode使用%代替斜杠作为转义符,等等。

常见字符集

ASCII(American Standard Code for Information Interchange / 美国信息交换标准代码)是基于拉丁字母的一套编码系统,首次发表于1967年,主要用于显示现代英语和其他西欧语言,等同于国际标准ISO/IEC 646。

Latin-1,是 ISO-8859-1 的别名,向下兼容 ASCII,除了 ASCII 字符,还收录了西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。

Unicode,最初有两个组织尝试统一字符编码,一个是 ISO(国际标准化组织)推出的 UCS “Universal Multiple Octet Coded Character Set” ,还有就是统一码联盟 Unicode(由各大企业及组织共同维护) 发布的 Unicode 项目 起初,UCS 和 unicode 并不兼容, 但这俩项目本身就是为了解决冲突而生,搞出两套有何意义? 后来 unicode 便与 UCS 统一了。目前的 Unicode 普遍采用的是 UCS-2

GB1803,全称:国家标准 GB 18030-2005《信息技术中文编码字符集》,是中华人民共和国现时最新的内码字集,是 GB 18030-2000《信息技术信息交换用汉字编码字符集基本集的扩充》的修订版,兼容 GBK、GB2312。

参考资料:

ASCII (American Standard Code for Information Interchange/美国信息交换标准代码),等同与ISO/IEC 646,也是Unicode编码中最初的一部分。 它包含128个字符,编码范围为00~7F,主要用于现代英语和其他西欧语言。 ASCII码表【Unicode官方】

Latin-1是ISO-8859-1的别名,编码范围为 00~FF,它包含了ASCII编码并新增了额外的编码,这些新增的编码主要是西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。 Latin-1字符集相对ASCII新增的字符【Unicode官方】

需要说明的是 UTF-8/16/32 并不是字符集,它们是 Unicode 字符集的三种编码方式,各自的特点如下:

UTF-8:

可变长编码,编码长度为1~4个字节。

UTF-16:

UTF-16 的编码长度是两个字节或四个字节,由于UTF-16相对于UTF-8长度更加固定,方便在内存中进行处理;也不像UTF-32那么浪费空间(对于很多双字节字符比UTF-8节省空间),所以像 C#,Java,JavaScript 程序内的字符串均为 UTF-16 编码。

UTF-32:

固定长度编码,编码长度为四个字节。

关于 Unicode 汉字部分的内容可参考下面的链接:

GB 18030,全称:国家标准 GB 18030-2005《信息技术中文编码字符集》,是中华人民共和国现时最新的内码字集,是 GB 18030-2000《信息技术信息交换用汉字编码字符集基本集的扩充》的修订版。

GB 18030 与 GB 2312-1980 和 GBK 兼容,共收录汉字70244个。 GB 18030 收录汉字包含了 ISO/IEC 10646.1: 2000 的全部27,484个CJK统一汉字,13个表意文字描述符、部分汉字部首和部件、欧元符号。

下面的图片显示了 GB 18030 编码在第一,第二字节部分所占的区域。

GB 18030 的主要特点及内容如下:

  • 采用多字节编码,每个字可以由 1 个、2 个或 4 个字节组成。
  • 支持中国国内少数民族的文字,不需要动用造字区。
  • 汉字收录范围包含繁体汉字以及日韩汉字
  • 单字节 ,其值从 0 到 0x7F,与 ASCII 编码兼容。
  • 双字节 ,与 GBK 标准兼容。
  • 四字节 ,第一个字节的值从 0x81 到 0xFE,第二个字节的值从 0x30 到 0x39,第三个字节从0x81 到 0xFE,第四个字节从 0x30 到 0x39。

其他标准简介:

  • GB 2312 编码:又称为 GB 2312-80,是一个简体中文字符集的中国国家标准,于1980年由中国国家标准总局发布,1981年5月1日实施,全称为《信息交换用汉字编码字符集基本集》,收录了6763个汉字和682个非汉字图形。
  • GBK 编码:1995年12月发布的汉字编码国家标准,是对GB2312编码的扩充,对汉字采用双字节编码。GBK字符集共收录21003个汉字,包含国家标准GB13000-1中的全部中日韩汉字,和BIG5编码中的所有汉字。
  • GB 13000 编码:为了便于多个文种的同时处理,国际标准化组织下属编码字符集工作组研制了新的编码字符集标准,ISO/IEC 10646。该标准第一次颁布是在1993年,当时只颁布了其第一部分,即ISO/IEC 10646.1: 1993,我国相应的国家标准是GB 13000.1-93《信息技术 通用多八位编码字符集(UCS) 第一部分:体系结构与基本多文种平面》。

各类编码的收录汉字统计

  • GB2312:6763个汉字
  • GBK:21003个汉字
  • GB18030-2000:27533个汉字
  • GB18030-2005:70244个汉字

URL encode 的目的是使用ASCII字符来表示可能包含各类字符的URL。

URL(统一资源定位符) 是 URI(统一资源标识符)的一个子集,另外一个子集是 URN(统一资源名称),URI 的规范由文件RFC3986来定义。

URL encode 编码也被称为 percent-encoding(百分号编码),它首先会将非ASCII字符进行编码,对于ASCII字符,它将ASCII字符分为三部分:1、保留字符 2、非保留字符 3、非安全字符,如下图所示。

“百分号编码”的格式为%后加上一个字节,既两位16进制编码,如:空格的编码为 %20。对于非ASCII字符则使用该字符的UTF-8编码,如:“你”字的UTF-8编码为:E4 BD A0,那么“百分号编码”的结果为:%E4%BD%A0。

主要的编码规则如下:

  • 1.非保留字符不进行编码
  • 2.除了保留字符和非保留字符外的所有字符,必须进行编码。
  • 3.保留字符不用于URI分隔符,而是在query的值部分时(?q=[值部分]),要对这里用到的保留字符进行编码。

SHA https://md5.cc/news0.aspx

Base64 是一种二进制到文本的编码方案,目的就是用可打印字符来表示二进制数据。编码规范定义在RFC2045等规范中。

具体的方法是,首先将原始的二进制数据以六位一组的方式进行分组,每一组六位二进制使用一个字符来表示,总共有64个字符。

Base64每次编码三个字节二进制数据到对应四个Base64字符,但是原始数据的字节数可能不是3的整除,可能余下一个字节,也可能余下两个字节。遇到这种情况,就需要在剩下的字节后面补零,直到其位数能够被6整除(因为Base64是对每6位进行编码的)。假如还剩下1个字节,即8位,那么需要再补4个0使其成为12位,这样就可以分为2组了;如果剩下2个字节,即16位,那么只需要再补2个0(18位)就可以分成3组了。最后再用普通方法做映射即可。

Base64中除了数字字母之外还存在 +、-、/、等符号,所以并不适合在URL中传输,为了解决这个问题,出现了一个无符号的改进版本Base62,顾名思义Base62就是使用62个字符来进行编码的方案,通常被用在短链接等场景。