我们都知道如何从键盘输入文字,不是吗?所以,请允许我挑战你在你最喜欢的文本编辑器中输入这段文字:?Ayumi于1993年搬到东京去追求她的事业?Dmitrii说这段文字很难输入,因为它包含:印刷符号,平假名日文字符,两个日本首都名称中的字母“o”,顶部有一个长音符,以符合普通罗马文字,最后是德米特里这个名字的西里尔拼写。毫无疑问,将这样的句子输入早期计算机是不可能的。这是因为早期的计算机使用有限的字符集,这些字符集与多种书写系统不兼容。今天,类似的限制已不复存在,我们稍后将在文中看到。计算机如何存储文本?计算机将字符存储为数字。然后他们通过表格将这些数字与有意义的字形对应起来。长期以来,计算机将每个字符存储为0到255之间的数字(恰好是一个字节长)。但这还不足以代表人类书写中使用的所有字符。解决这个问题的诀窍是,根据你生活在世界的哪个部分,系统使用不同的查找表。这是一张在法国广泛使用的ISO8859-15对照表:ISO8859-15编码如果你住在俄罗斯,你的电脑可能会使用KOI8-R或Windows-1251编码。现在让我们假设我们使用的是后者:Windows-1251编码是一种流行的选择,用于存储使用西里尔字母书写的文本对于最大128的数字,两个表是相同的。这个范围对应的是US-ASCII,是不同字符表之间的最小兼容。对于128之后的数字,两个表是完全不同的。例如,根据Windows-1251,字符串“saidДмитрий”将被存储为:1159710510032196236232242240232233根据计算机科学的常规方法,这十二个数字可以写成更多紧凑十六进制:7361696420c4ece8f2f0e8e9如果Dmitry将此文件发送给我,我打开它后可能会看到:said?ìèòeèé此文件看起来已损坏,但实际上并没有。存储在文件中的数据,即数字,没有改变。显示的字符对应于另一个表中的数据,而不是最初写入文本的代码表中的数据。举个例子,我们就以“Д”这个字符为例。根据Windows-1251,“Д”的数字编码为196(c4)。文件中存储的只是数字196。这个数字对应于ISO8859-15中的“?”。这就是为什么我的电脑错误地认为字形“?”是应该显示的字形。当写入相同的文本文件然后再次读取但使用不同的编码还有一点,您仍然会不时看到一些配置错误的网站显示,或者用户邮箱代理发送到收件人计算机的电子邮件消息做出错误假设的消息关于使用的字符编码。这样的毛刺有时被称为乱码(LCTT译注:原词是mojibake,源自日文直译け)。幸运的是,这种情况在今天越来越少见。法国电影发行商网站上的Mojibake示例。网站名称已更改,以保护无辜者。Unicode拯救世界我解释了在不同国家之间交换文件时可能遇到的编码问题。但事情可能更糟,同一国家的不同制造商可能不会使用相同的代码。如果您曾在80年代将文件从Mac传输到PC,您就会明白我的意思。不知道是不是巧合。Unicode项目始于1987年。领导者来自Xerox和……Apple。使用的任何文本。最初的Unicode项目被限制为65536个不同的字符(每个字符由16位表示,或每个字符两个字节)。事实证明,这个数字远远不够。因此,在1996年,Unicode被扩展到支持多达100万个不同的代码点。粗略地说,“代码点”可用于标识字符表中的条目。Unicode项目的核心任务之一是管理世界上正在使用(或已经使用)的字母、符号、标点符号和其他文字,并为每个条目分配一个代码点,以准确识别对应的字符.这是一个庞大的项目:给你一个想法,2017年发布的Unicode第10版定义了超过136,000个字符,涵盖139个现代和历史文字。由于存在如此多的可能性,基本编码需要每个字符32位(即4字节)。但对于主要使用US-ASCII范围内的字符的文本,每个字符4个字节意味着存储需求增加4倍,传输这些文本的带宽增加4倍。将文本编码为UTF-32需要每个字符4个字节所以除了UTF-32之外,UnicodeConsortium还定义了更节省空间的UTF-16和UTF-8编码,它们使用16位和8位。但是如何仅用8位存储超过100,000个不同的值呢?事实是,你不能。但是这里的技巧是用一个代码值(UTF-8中的8位和UTF-16中的16位)来存储一些最常用的字符。然后用几个码值来存放一些最不常用的字符。所以UTF-8和UTF-16都是变长编码。尽管存在缺陷,但UTF-8是空间和时间效率之间的一个很好的折衷。更不用说UTF-8向后兼容Unicode之前的大多数1字节编码,因为UTF-8的设计使得任何有效的US-ASCII文件都是有效的UTF-8文件。您也可以说UTF-8是US-ASCII的超集。今天,没有理由不使用UTF-8编码。当然,除非您正在编写需要多字节编码的主要语言,否则您必须处理一些遗留的遗留系统。在下面的两张图片中,您可以自己比较同一字符串的UTF-16和UTF-8编码。特别要注意,UTF-8使用一个字节来存储拉丁字母表中的字符,但它使用两个字节来存储西里尔字母表中的字符。这是在Windows-1251西里尔编码中存储相同字符所需空间的两倍。UTF-16是一种可变长度编码,需要2个字节来对大多数字符进行编码。有些字符仍然需要4个字节(例如UTF-8是一种可变长度编码,每个字符需要1、2、3或4个字节,这些用于键入的内容是什么?如何使用它?啊......这不是一件坏事稍微了解一下您的计算机的功能和局限性及其底层机制。尤其是因为我们马上就要讲到Unicode和十六进制。现在……让我们来谈谈历史吧。真的只是一点点,我保证。....自80年代以来,计算机键盘在Shift键旁边通常有一个Compose(有时也标记为Multi键)当您按下此键时,您将进入Compose模式。一旦进入此模式,你可以通过输入助记符来输入你键盘上没有的字符。例如,在组合模式下,键入RO生成字符最近在现代键盘上看到了Compose键。这可能是因为DominantPC不再使用它了。Bu在Linux(可能还有其他)上,您可以模拟Compose键。此设置可以通过GUI打开,在大多数桌面环境中称为“键盘”控制面板:但具体步骤取决于您的桌面环境和版本。如果您成功启用了该设置,请不要犹豫,在评论中分享您在计算机上执行的确切步骤。(LCTT译注:如果有读者想尝试的话,建议将Compose键设置为capslock键,或者其他不常见的键。Ctrl和Alt会被大多数GUI程序优先识别为功能键。有还有一些我自己实验遇到的问题,在打开Compose键之前,一定要关闭capslock,输入法一定要切换成英文,组合模式输入是区分大小写的。我试验的系统是Ubuntu22.04LTS。)至于我自己,我现在假设您正在使用默认的Shift+AltGr组合来模拟Compose键。(LCTT证明注:AltGr是欧洲键盘上的右Alt键,相当于国际键盘上的Ctrl+Alt。)因此,作为一个实际示例,尝试键入“LEFT-POINTINGDOUBLEANGLEQUOTATIONMARK”(LCTT译注:Guillemet,在法语和部分欧洲语言中是引号,与中文标题编号不同),可以输入Shift+AltGr<<(不需要一直按住Shift+AltGr同时输入助记符)。如果你成功输入了这个符号,你应该也能猜到如何输入“RIGHT-POINTINGDOUBLEANGLEQUOTATIONMARK(右双角引号)”。再看一个例子,试试Shift+AltGr----生成一个“EMDASH(长破折号)”(LCTT译注:中文输入法的长破折号由两个“EM”组成DASH”组合)。为此,您需要按下主键盘上的连字符减号键,而不是数字键盘上的连字符减号键。值得注意的是,组合键在非GUI环境中也可以使用。但这取决于是否你使用的是X11控制台还是纯文本控制台,它们支持的组合键顺序是不同的。在控制台上,你可以使用命令dumpkeys查看支持的组合键列表(LCTT译注:可能需要root权限):dumpkeys--compose-only实现了。要了解Gtk支持的助记符,可以查看页面:https://help.ubuntu.com/community/GtkComposeTable是否可以避免对Gtk字符组合的依赖?也许我是纯粹主义者,但我对Gtk硬编码Compose键的方式感到遗憾。毕竟,并非所有GUI应用程序都会使用Gtk库拉里。如果我想添加自己的助记符,我必须重新编译Gtk。幸运的是,X11层也支持字符组合。在过去,它是通过古老的X输入法(XIM)。这种方法在比基于Gtk的字形更低的级别上工作,同时具有灵活性并与许多X11应用程序兼容。例如,假设我只是想添加-->组合来输入字符→(U+2192,RIGHTWARDSARROW(向右箭头)),我只需要新建一个~/.XCompose文件并写入以下代码:cat>~/.XCompose<
