前言
本文旨在为初学者提供有关计算机字符编码的基础知识,以帮助他们初步理解计算机中字符编码的概念。鉴于我个人知识的限制,如有不准确之处,欢迎指正并提供建议。
文中部分内容参考ChatGPT,在此感谢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)设备控制10001 0010180x12DC2 (device control 2)设备控制20001 0011190x13DC3 (device control 3)设备控制30001 0100200x14DC4 (device control 4)设备控制40001 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字符00011 0001490x311字符10011 0010500x322字符20011 0011510x333字符30011 0100520x344字符40011 0101530x355字符50011 0110540x366字符60011 0111550x377字符70011 1000560x388字符80011 1001570x399字符90011 1010580x3A:冒号0011 1011590x3B;分号0011 1100600x3C</tdtd 小于/td/trtrtd 0011 1101/tdtd 61/tdtd 0x3D/tdtd =/tdtd 等号/td/trtrtd 0011 1110/tdtd 62/tdtd 0x3E/tdtd >大于0011 1111630x3F?问号0100 0000640x40@电子邮件符号0100 0001650x41A大写字母A0100 0010660x42B大写字母B0100 0011670x43C大写字母C0100 0100680x44D大写字母D0100 0101690x45E大写字母E0100 0110700x46F大写字母F0100 0111710x47G大写字母G0100 1000720x48H大写字母H0100 1001730x49I大写字母I01001010740x4AJ大写字母J0100 1011750x4BK大写字母K0100 1100760x4CL大写字母L0100 1101770x4DM大写字母M0100 1110780x4EN大写字母N0100 1111790x4FO大写字母O0101 0000800x50P大写字母P0101 0001810x51Q大写字母Q0101 0010820x52R大写字母R0101 0011830x53S大写字母S0101 0100840x54T大写字母T0101 0101850x55U大写字母U0101 0110860x56V大写字母V0101 0111870x57W大写字母W0101 1000880x58X大写字母X0101 1001890x59Y大写字母Y0101 1010900x5AZ大写字母Z0101 1011910x5B[开方括号0101 1100920x5C\反斜杠0101 1101930x5D]闭方括号0101 1110940x5E^脱字符0101 1111950x5F_下划线0110 0000960x60`开单引号0110 0001970x61a小写字母a0110 0010980x62b小写字母b0110 0011990x63c小写字母c0110 01001000x64d小写字母d0110 01011010x65e小写字母e0110 01101020x66f小写字母f0110 01111030x67g小写字母g0110 10001040x68h小写字母h0110 10011050x69i小写字母i0110 10101060x6Aj小写字母j0110 10111070x6Bk小写字母k0110 11001080x6Cl小写字母l0110 11011090x6Dm小写字母m0110 11101100x6En小写字母n0110 11111110x6Fo小写字母o0111 00001120x70p小写字母p0111 00011130x71q小写字母q0111 00101140x72r小写字母r0111 00111150x73s小写字母s0111 01001160x74t小写字母t0111 01011170x75u小写字母u0111 01101180x76v小写字母v0111 01111190x77w小写字母w0111 10001200x78x小写字母x0111 10011210x79y小写字母y0111 10101220x7Az小写字母z0111 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+7F0xxxxxxxU+0080 - U+07FF110xxxxx 10xxxxxxU+0800 - U+FFFF1110xxxx 10xxxxxx 10xxxxxxU+010000 - U+10 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx转换时,填充空位,从低位(右)至高位(左),高位上多余的0直接丢弃
[table][tr]字符码点码点二进制UTF-8编码(二进制)UTF-8编码(十六进制)[/tr][tr][td]A[/td][td]U+41[/td][td](0)1000001[/td][td](0)1000001[/td][td]0x41[/td][/tr][tr][td]π[/td][td]U+03c0[/td][td](00000)011 11000000[/td][td](110)01111 (10)000000[/td][td]0xCF80[/td][/tr][tr][td]
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |