计算机字符编码入门篇

前言

本文旨在为初学者提供有关计算机字符编码的基础知识,以帮助他们初步理解计算机中字符编码的概念。鉴于我个人知识的限制,如有不准确之处,欢迎指正并提供建议。

文中部分内容参考GPT,在此感谢ppword的大力支持。

一、什么是二进制

二进制是一种数字表示系统,它只使用两个数字:0和1。与十进制不同,它使用基数2,这意味着每个位置的数字的权值都是2的幂。在二进制中,数字的每一位表示一种状态,通常用于计算机内部的数据表示和处理。

以下是一些二进制数字示例以及它们在十进制中的对应值:

  • 二进制的0和1分别表示十进制的0和1。
  • 0(二进制)表示0(十进制)
  • 1 (二进制)表示1(十进制),加1后。
  • 10(二进制)表示2(十进制),这是因为在二进制中,当某一位达到1后,它会进位到下一位。
  • 11(二进制)表示3(十进制),再加1后。
  • 100(二进制)表示4(十进制),再次进位,依次类推。

简而言之,二进制是一种由0和1组成的数字系统,通过排列不同位置上的0和1来表示各种数字。这种系统在计算机内部非常常见,因为计算机使用开关状态来处理信息,其中0表示关闭或低电平,1表示打开或高电平,因此很适合用二进制来表示和操作数据。

二、为什么计算机采用二进制来表示数据

计算机采用了二进制来表示数据,主要是因为电子计算机的内部元件(例如晶体管和电路)可以轻松地表示和处理两种状态,即开和关,或者电平高和电平低。这些元件的工作方式使得二进制非常适合作为计算机的内部数据表示方法的几个原因:

  • 电子开关:计算机内部使用的主要元件是电子开关,这些开关只有两种状态,打开和关闭。这与二进制的两个值(0和1)非常契合,因此计算机可以用非常简单的方式来表示和处理数据。

  • 稳定性和可靠性:二进制状态更稳定,容易维护和判断。由于电子元件的物理特性,它们能够可靠地保持在开或关的状态,减少了数据传输和存储中的误差。

  • 逻辑简单性:二进制非常适合逻辑运算。计算机中的许多操作都涉及到逻辑运算,例如AND、OR、NOT等。这些运算在二进制中非常直观和容易实现。

现在我们知道了,计算进它只能表示一堆由0或1组成的东西,那我们的“a、b、c、d”怎么办,它能表示的了么?

三、计算机怎么样表示文本

这时,我们的大美丽同学就跳出来说,这个还不简单,我们只要给每一个我们要用到的字符,分别给它们分配一个固定的0和1的组合体,以后大家都按这个标准来,不就解决了么。

她很快就给制作出来了这么一个对应规则。

1、ASCII码

这就是大名鼎鼎的ASCII码表

二进制(Bin)十进制(Dec)十六进制(Hex)缩写/字符解释
0000 000000x00NUL(null)空字符
0000 000110x01SOH(start of headline)标题开始
0000 001020x02STX (start of text)正文开始
0000 001130x03ETX (end of text)正文结束
0000 010040x04EOT (end of transmission)传输结束
0000 010150x05ENQ (enquiry)请求
0000 011060x06ACK (acknowledge)收到通知
0000 011170x07BEL (bell)响铃
0000 100080x08BS (backspace)退格
0000 100190x09HT (horizontal tab)水平制表符
0000 1010100x0ALF (NL line feed, new line)换行键
0000 1011110x0BVT (vertical tab)垂直制表符
0000 1100120x0CFF (NP form feed, new page)换页键
0000 1101130x0DCR (carriage return)回车键
0000 1110140x0ESO (shift out)不用切换
0000 1111150x0FSI (shift in)启用切换
0001 0000160x10DLE (data link escape)数据链路转义
0001 0001170x11DC1 (device control 1)设备控制1
0001 0010180x12DC2 (device control 2)设备控制2
0001 0011190x13DC3 (device control 3)设备控制3
0001 0100200x14DC4 (device control 4)设备控制4
0001 0101210x15NAK (negative acknowledge)拒绝接收
0001 0110220x16SYN (synchronous idle)同步空闲
0001 0111230x17ETB (end of trans. block)结束传输块
0001 1000240x18CAN (cancel)取消
0001 1001250x19EM (end of medium)媒介结束
0001 1010260x1ASUB (substitute)代替
0001 1011270x1BESC (escape)换码(溢出)
0001 1100280x1CFS (file separator)文件分隔符
0001 1101290x1DGS (group separator)分组符
0001 1110300x1ERS (record separator)记录分隔符
0001 1111310x1FUS (unit separator)单元分隔符
0010 0000320x20(space)空格
0010 0001330x21!叹号
0010 0010340x22"双引号
0010 0011350x23#井号
0010 0100360x24$美元符
0010 0101370x25%百分号
0010 0110380x26&和号
0010 0111390x27闭单引号
0010 1000400x28(开括号
0010 1001410x29)闭括号
0010 1010420x2A*星号
0010 1011430x2B+加号
0010 1100440x2C,逗号
0010 1101450x2D-减号/破折号
0010 1110460x2E.句号
0010 1111470x2F/斜杠
0011 0000480x300字符0
0011 0001490x311字符1
0011 0010500x322字符2
0011 0011510x333字符3
0011 0100520x344字符4
0011 0101530x355字符5
0011 0110540x366字符6
0011 0111550x377字符7
0011 1000560x388字符8
0011 1001570x399字符9
0011 1010580x3A:冒号
0011 1011590x3B;分号
0011 1100600x3C<小于
0011 1101610x3D=等号
0011 1110620x3E>大于
0011 1111630x3F?问号
0100 0000640x40@电子邮件符号
0100 0001650x41A大写字母A
0100 0010660x42B大写字母B
0100 0011670x43C大写字母C
0100 0100680x44D大写字母D
0100 0101690x45E大写字母E
0100 0110700x46F大写字母F
0100 0111710x47G大写字母G
0100 1000720x48H大写字母H
0100 1001730x49I大写字母I
01001010740x4AJ大写字母J
0100 1011750x4BK大写字母K
0100 1100760x4CL大写字母L
0100 1101770x4DM大写字母M
0100 1110780x4EN大写字母N
0100 1111790x4FO大写字母O
0101 0000800x50P大写字母P
0101 0001810x51Q大写字母Q
0101 0010820x52R大写字母R
0101 0011830x53S大写字母S
0101 0100840x54T大写字母T
0101 0101850x55U大写字母U
0101 0110860x56V大写字母V
0101 0111870x57W大写字母W
0101 1000880x58X大写字母X
0101 1001890x59Y大写字母Y
0101 1010900x5AZ大写字母Z
0101 1011910x5B[开方括号
0101 1100920x5C\反斜杠
0101 1101930x5D]闭方括号
0101 1110940x5E^脱字符
0101 1111950x5F_下划线
0110 0000960x60`开单引号
0110 0001970x61a小写字母a
0110 0010980x62b小写字母b
0110 0011990x63c小写字母c
0110 01001000x64d小写字母d
0110 01011010x65e小写字母e
0110 01101020x66f小写字母f
0110 01111030x67g小写字母g
0110 10001040x68h小写字母h
0110 10011050x69i小写字母i
0110 10101060x6Aj小写字母j
0110 10111070x6Bk小写字母k
0110 11001080x6Cl小写字母l
0110 11011090x6Dm小写字母m
0110 11101100x6En小写字母n
0110 11111110x6Fo小写字母o
0111 00001120x70p小写字母p
0111 00011130x71q小写字母q
0111 00101140x72r小写字母r
0111 00111150x73s小写字母s
0111 01001160x74t小写字母t
0111 01011170x75u小写字母u
0111 01101180x76v小写字母v
0111 01111190x77w小写字母w
0111 10001200x78x小写字母x
0111 10011210x79y小写字母y
0111 10101220x7Az小写字母z
0111 10111230x7B{开花括号
0111 11001240x7C|垂线
0111 11011250x7D}闭花括号
0111 11101260x7E~波浪号
0111 11111270x7FDEL (delete)删除

好家伙,密密麻麻的,还真是什么都有。有些同学看了之后,不免以中就有一些疑惑了。

1)为什么这“二进制”那列,整整齐齐的都是8个0或1的组合?

当ASCII码被设计时,主要用途是在早期计算机和通信系统中传输文本字符。这种情况下,128个字符通常足够表示英语和一些其他常用语言的字符。因此,7位提供的字符范围正好足够。之所以写成8位,应该和“字节”有关,一个字节刚好是8位,在这里习惯性的把最高位补上0。

字节(byte)这个单位的起源可以追溯到早期计算机领域的发展历史。字节的定义和大小不是一开始就确定的,而是随着计算机技术的发展和标准化逐渐形成的。

以下是一些关于字节和为什么一字节通常被定义为8位的解释:

  • 早期计算机架构:早期计算机使用了各种不同的数据结构和字长(一个字长是指一个计算机可以一次处理的二进制位数)。在这个时期,字节的大小并不是一个统一的标准。不同的计算机系统使用了不同大小的字节,如6位、7位或9位。

  • 8位字节的普及:在计算机发展的早期阶段,一些计算机科学家和工程师开始推崇使用8位字节。这种设计选择有几个原因:

    • 8位字节提供了256个不同的组合,足够表示各种字符、数字、符号和控制字符,这对于字符编码来说是非常有用的。
    • 8位字节相对于其他大小的字节更容易在硬件上实现,因为它刚好是2的幂次方(2^3=8),这对于计算机设计来说更加简单和高效。
  • 标准化:随着时间的推移,8位字节逐渐成为一种标准,并在计算机领域广泛普及。这种标准化有助于确保不同计算机系统之间的兼容性,同时也简化了数据交换和编程。

2)为什么表中还有一些奇怪的字符,例如回车、换行、退格等?

这些控制字符用于控制打印机、终端和通信设备的行为。这些字符不是可打印字符,但在通信和控制领域中非常重要。

3)按前面所说,“0000 0001”应该是表示1,那这表里的怎么又变成“0011 0001”表示1了呢?

您的观察是正确的,二进制中的 “0000 0001” 表示的确实是数字 1,但这不同于 ASCII 码中表示数字字符 “1” 的方式。ASCII 码使用 7 位二进制编码字符,而 “0011 0001” 是表示字符 “1” 的 ASCII 编码值。
比如“0100 0001”,你把它当二进制的数字看,它就是65,把它当字符看,它就是“A”,反正就是全凭你一张嘴,咋说咋有理。

4)那一列“十六进制”又是什么鬼?

十六进制也是一种数字表示系统,它使用16个不同的字符来表示数据,包括0-9和A-F。
我们观察一下其中一个二进制数,如:0111 0001,如果都要这么写确实不方便,再来看一下它对应的十六进制值:0x71(数字前带0x的都是十六进制),这样就好读也更方便书写。
从这不难看出,前面的四位0111刚好是0x7,后面的是0x1,四位的二进制刚好转换成1位的十六进制(2^4=16)。

所以选择使用十六进制的原因有:

  • 紧凑性:十六进制表示方式比二进制更紧凑。在十六进制中,一个数字可以表示4个二进制位。这使得在处理和表示大量二进制数据时,十六进制更容易阅读和管理。特别是在编程和计算机内部数据处理方面,使用十六进制可以提高可读性。

  • 易于转换:十六进制和二进制之间的转换非常容易。每个十六进制数字对应于4个二进制位,因此可以很容易地将十六进制数转换为二进制,反之亦然。这使得在编程和计算机领域中,可以轻松地在二进制和十六进制之间切换,以便于调试和数据处理。

5)那ASCII编码这么好,难道就没什么问题么?
  • ASCII编码只使用7位二进制来表示字符,因此只能表示128个不同的字符。这足够用来表示英文字母、数字和一些基本符号,但对于其他语言的字符或特殊符号来说,就不够了。这对于国际化的计算机应用来说是一个巨大的问题,因为不同国家和地区使用不同的字符集。

为了解决ASCII编码的局限性,Unicode应运而生。

2、Unicode字符编码标准

Unicode(统一码)是一个国际标准,是一种字符编码标准,用于表示世界上几乎所有已知的书写系统的字符和符号。它的主要目的是为了解决不同字符编码标准之间的兼容性问题,确保文本在不同计算机系统、操作系统和编程语言之间能够正确地显示和交换。

在 Unicode 中,每个字符都被分配一个唯一的数字代码点,这个代码点可以用来表示该字符。Unicode 编码包括了各种语言中的字母、数字、标点符号、符号、特殊字符和控制字符等。它涵盖了世界上许多不同的语言,包括英语、中文、日语、阿拉伯语、希伯来语、俄语等等。

代码点(Code Points): Unicode 中的每个字符都被分配一个唯一的代码点,这是一个用来标识字符的整数值。这个代码点通常以 U+ 开头,后面跟随一个表示十六进制数的数字,例如 U+0041 表示拉丁字母 “A”。Unicode 定义了一个代码点范围,从 U+0000 到 U+10FFFF。

  • 那如此多的代码点,又是怎么划分区域(平面)的,每个区域又分别表示什么样的字符,看下图:
平面码点范围平面名称描述
0U+0000 - U+FFFF基本多文种平面(Basic Multilingual Plane)包含了大部分常用字符,如拉丁字母、希腊字母、标点符号、数字、常见汉字
1U+010000 - U+01FFFF增补多文种平面-A(SMP-A)包括一些不常用的字符和古代文字,如伊斯兰文、埃及象形文字等
2U+020000 - U+02FFFF增补多文种平面-B(SMP-B)用于容纳更多的稀有和历史字符,如饰字符和表意字符描述
3U+030000 - U+03FFFF增补多文种平面-C(SMP-C)包括更多的字符,如尼亚文字、埃及草书等
4U+040000 - U+04FFFF增补多文种平面-D(SMP-D)包括一些亚洲文字、修饰符和 Emoji 表情符号
5U+050000 - U+05FFFF增补多文种平面-E(SMP-E)包含一些其他语言的字符,如摩尔斯电码、装饰符等
6U+060000 - U+06FFFF增补多文种平面-F(SMP-F)主要用于扩展埃及象形文字,包括更多的字符和修饰符
7U+070000 - U+07FFFF增补多文种平面-G(SMP-G)用于收容带有特殊符号和修饰符的文字,如印度的许多脚本
8U+080000 - U+08FFFF增补多文种平面-H(SMP-H)包括少数民族文字、修饰符、数字和特殊符号
9U+090000 - U+09FFFF增补多文种平面-I(SMP-I)主要用于扩展已存在的字符集
10U+0A0000 - U+0AFFFF增补多文种平面-J(SMP-J)继续扩展已有字符集,包括一些汉字和其他字符
11U+0B0000 - U+0BFFFF增补多文种平面-K(SMP-K)用于存放汉字的变体和历史汉字
12U+0C0000 - U+0CFFFF增补多文种平面-L(SMP-L)主要包括中世纪的拉丁文字、特殊符号和 Emoji 扩展
13U+0D0000 - U+0DFFFF增补多文种平面-M(SMP-M)包含修饰符、音符和 Emoji 扩展
14U+0E0000 - U+0EFFFF增补多文种平面-N(SMP-N)包括 Emoji 扩展,如符号、动物和食物
15U+0F0000 - U+0FFFFF增补多文种平面-O(SMP-O)用于 Emoji 扩展,包括情感符号和其他特殊符号
16U+100000 - U+10FFFF增补多文种平面-P(SMP-P)用于存放一些音乐符号和 Emoji 扩展

常用字符Unicode编码范围:

字符类型码点范围
汉字U+4e00 - U+9fa5十进制[19968 - 40869]
数字U+0030 - U+0039十进制[48 - 57]
小写字母U+0061 - U+007a十进制[97 - 122]
大写字母U+0041 - U+005a十进制[65 - 90])

标准定好了,这下万事大吉了,不管什么字符,总能够有办法表示出来了,如果再有新的字符,大不了再多定义几个平面,码点多放几个字节就搞定了。

那标准有了,又要怎么使用呢?

3、Unicode 字符编码方案

1)UTF-16

UTF-16 使用16位(2字节)来编码这些字符,因此它足够表示 BMP 中的字符,但对于 BMP 之外的字符,UTF-16 需要使用额外的机制来处理。
最早出现的 UTF-16 并不是为了表示所有的 Unicode 字符,而是为了表示 Unicode 基本多文种平面(Basic Multilingual Plane,BMP)中的字符。BMP 包含了大多数常用的字符,包括拉丁字母、数字、标点符号、常见汉字等等。

特点:
  • 兼容性: UTF-16 具有与 ASCII 和基本多文种平面(BMP)兼容的特点。ASCII 字符在 UTF-16 中使用单个16位编码表示,这使得 UTF-16 可以无缝处理包含 ASCII 字符的文本。

  • 变长编码: UTF-16 是一种变长编码,大多数常用字符和 BMP 中的字符使用2个字节表示,而增补多文种平面(SMP)中的字符使用4个字节表示。这种设计在某些情况下可以节省存储空间,但也意味着编码单元的大小不固定。

  • 支持大多数字符: UTF-16 能够表示大多数 Unicode 字符,包括各种语言的字符、符号和特殊符号。

不足:
  • 变长编码: UTF-16 的变长编码特性意味着字符的编码单元大小不固定,这可能导致处理文本数据时的复杂性。对于 SMP 中的字符,需要额外的编码单元(代理对),这增加了处理的复杂性。

  • 字节序问题: UTF-16 存在字节序问题,即字节序(Big Endian 或 Little Endian)可能影响文本的正确解释。这可能导致在不同系统之间或在网络传输中出现问题。

  • 不适用于某些字符: 尽管 UTF-16 能够表示大多数字符,但仍然有一些字符,特别是一些辅助语言和古代文字字符,无法直接表示,需要使用组合或其他机制。

从上面不难看出,使用UTF-16的时候,不管表示什么字符,至少需要2个字节。那对于那些原本只要一个字节就能表示出来的字符来说,不管是在存储还是网络传输的时候都有不少的浪费,所以就出现了UTF-8。

2)UTF-8

UTF-8 是一种变长编码,它可以使用1到4个字节来表示不同的 Unicode 码点。对于大多数常用的字符,UTF-8 使用1到3个字节,只有少数罕见字符需要4个字节。这种编码方式节省了存储空间,并且适合在互联网和计算机系统中广泛使用。

UTF-8 的编码规则如下:
  • 对于单字节的字符,字节的第一位设为 0,后面 7 位为其代码点。
  • 对于 n 字节的符号( n > 1),第一个字节的前 n 位都设为 1,第 n + 1 位设为 0,后面字节的前两位一律设为 10 。剩下的没有提及的二进制位,全部为为其代码点。
码点范围(十六进制)UTF-8编码(二进制)
U+00 - U+7F0xxxxxxx
U+0080 - U+07FF110xxxxx 10xxxxxx
U+0800 - U+FFFF1110xxxx 10xxxxxx 10xxxxxx
U+010000 - U+10 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

转换时,填充空位,从低位(右)至高位(左),高位上多余的0直接丢弃

  • 示例
字符码点码点二进制UTF-8编码(二进制)UTF-8编码(十六进制)
AU+41(0)1000001(0)10000010x41
πU+03c0(00000)011 11000000(110)01111 (10)0000000xCF80
😀U+1F642(000)00001 11110110 01000010(11110)000 (10)011111 (10)011001 (10)0000100xF09F9892
特点:
  • 兼容性: UTF-8 兼容 ASCII,这意味着任何有效的 ASCII 文本都是有效的 UTF-8 文本。这种兼容性使得从 ASCII 过渡到 Unicode 变得无缝,并且已有的 ASCII 文本无需任何修改即可在 UTF-8 中使用。

  • 变长编码: UTF-8 是一种变长编码方案,可以使用1到4个字节来表示不同的 Unicode 码点。这使得 UTF-8 非常节省存储空间,因为常用字符通常只需要1到3个字节。

  • 全球支持: UTF-8 能够表示世界上几乎所有已知的语言的字符,包括拉丁字母、亚洲文字、希腊字母、西里尔字母、非洲字符等等。这使得 UTF-8 成为一种通用的字符编码方案,适用于全球范围内的文本处理。

  • 互联网标准: UTF-8 是互联网上最常用的字符编码方案之一,几乎所有的现代网络通信协议和网页内容都使用 UTF-8 来表示文本数据。这有助于实现全球化和多语言支持。

  • 适用性广泛: UTF-8 在各种操作系统、编程语言和应用程序中得到广泛支持,使得它成为开发者和用户的首选编码方案。

不足:
  • 不适合固定大小的数据结构: 由于 UTF-8 是变长编码,它不适合用于某些需要固定大小数据结构的场景,如数据库表的字段、二进制文件格式等。在这些情况下,UTF-32 或其他固定大小编码可能更合适。

  • 处理复杂字符需要额外计算: 对于 SMP(增补多文种平面)中的字符或 Emoji 表情符号,UTF-8 需要使用多个字节来表示,这可能需要额外的计算和处理,不如 UTF-32 那样直观。

  • 不适合随机访问: 由于 UTF-8 是变长编码,要在文本中进行随机访问(如查找第 n 个字符)需要遍历整个文本,而 UTF-32 更适合这种操作。

  • 编码和解码复杂性: UTF-8 的编码和解码算法相对复杂,需要额外的计算来确定字符的边界和编码单元的数量。这可能对某些性能敏感的应用产生一些开销。

3)UTF-32

UTF-32是Unicode字符集的一种完全统一的编码方案,每个字符都用32位(4字节)表示,这使得它可以容纳Unicode字符集中的任何字符。

特点:
  • 固定长度编码:UTF-32采用固定长度的编码,每个字符都用相同数量的字节表示。这样的编码方案使得在处理文本时更加简单和高效,因为不需要像变长编码(如UTF-8和UTF-16)那样在字符之间查找分隔符。

  • 简化文本处理:UTF-32编码在处理文本时具有一定的优势,特别是在需要快速随机访问字符的情况下。由于每个字符都占据相同数量的字节,可以轻松计算和索引字符的位置。

不足:
  • 占用更多存储空间:UTF-32通常占用比UTF-8和UTF-16更多的存储空间,特别是对于包含大量ASCII字符的文本。
  • 内存占用:对于大量文本数据,UTF-32需要更多的内存,可能不适用于内存受限的环境。
  • 不适合网络传输:UTF-32的固定长度编码会增加网络传输的数据量。

结束

当然,除了上述提到的字符编码方案,世界上还存在着众多其他编码标准,涵盖了各种语言和地区的需求。例如,中文有GB2312、GBK、GB18030、Big5等多种编码方案,而Latin-1等字符编码则是一种局限于特定语言或地区的标准。有机会我们将继续探讨这些编码标准,以便更好地理解它们的起源、应用和发展历程。感谢大家的支持与关注!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值