当前位置: 首页 > 科技观察

文字大战及其救世主Unicode

时间:2023-03-21 23:17:12 科技观察

我们都知道如何从键盘输入文字,不是吗?所以,请允许我挑战你在你最喜欢的文本编辑器中输入这段文字:?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<:U2192#RIGHTWARDSARROWEOT然后你可以开始一个新的X11应用程序,强制库使用XIM作为输入法,并开始测试:GTK_IM_MODULE="xim"QT_IM_MODULE="xim"xterm新的组合排序应该可以导入到您刚刚启动的应用程序中。我鼓励您使用man5compose进一步研究compose文件格式。将以下两行添加到您的~/.profile以使XIM成为所有应用程序的默认输入法。这些更改将在您下次登录计算机时生效:exportGTK_IM_MODULE="xim"exportQT_IM_MODULE="xim"这很酷,不是吗?这样你就可以自由添加你想要的组合和排序。在默认的XIM设置中已经有几个有趣的组合。尝试键入组合键LLAP。但我不得不提到两个缺陷。XIM比较老,只适合我们这些不需要多字节输入法的人。其次,当你使用XIM作为输入法时,不能使用Ctrl+Shift+u加码位来输入Unicode字符。什么?稍等?我还没谈过?现在说说:如果我需要的字符没有对应的排序组合键怎么办?组合键是一个很好的工具,它可以用来输入一些键盘上没有的字符。但是默认的组合集是有限的,切换XIM和为一个你一生只用过一次的角色定义一个新的组合顺序是很麻烦的。但这会阻止您在同一段落中混合使用日文、拉丁文和西里尔文字符吗?显然不是,感谢Unicode。例如,名字“あゆみ”由三个字母组成:“HIRAGANALETTERA(平假名字母あ)”(U+3042)“HIRAGANALETTERYU(平假名字母ゆ)”(U+3086)和“HIRAGANALETTERMI”(平假名み)”(U+307F)上面提到了Unicode字符的正式名称,按照惯例全部大写。在他们的名字之后,你可以找到他们的Unicode代码点,写在括号之间,写成16位十六进制数。这会让你想到什么吗?无论如何,一旦你知道了一个字符的代码点,你可以按以下组合输入它:Ctrl+Shift+u,然后XXXX(你想要代码点的字符的十六进制值),然后按Enter。简而言之,如果您在键入代码点时没有松开Ctrl+Shift,则不必按Enter。不幸的是,此功能是在库级别而不是X11级别实现的,因此对它的支持在应用程序之间并不统一。对于LibreOffice,您必须使用主键盘输入代码点。在基于Gtk的应用程序中,接受来自数字键盘的输入。最后,当我在我的Debian系统上使用控制台时,我发现了一个类似的功能,但它需要你按Alt+XXXXX,其中XXXXX是你想要的十进制代码点的字符。我很好奇这是Debian特有的特性,还是因为我使用的语言环境(Locale)是en_US.UTF-8。如果您对此有更多信息,我很乐意在评论中阅读它们!GUI控制台字符Ctrl+Shift+u3042EnterAlt+12354あCtrl+Shift+u3086EnterAlt+12422ゆCtrl+Shift+u307FEnterAlt+12415mi死键必须)依赖于Compose键。键盘上的某些键专用于创建字符组合。这些键称为死键。那是因为当你按下它们一次时,看起来没有任何反应,但它们会悄悄地改变你下一次按键产生的字符。这种行为受到机械打字机的启发:使用机械打字机时,按下死键会打印一个字符,但不会移动类型板。然后下一次击键将在同一个地方打印另一个字符。视觉效果是两次击键的组合。我们在法语中经常使用这个。例如,要键入字母?,我必须先按死键¨,然后再按e键。同样,西班牙语键盘也有死键~。而在北欧语系下的键盘布局中,可以找到°键。我可以阅读这份清单很长时间。饥饿的死键显然,并不是所有的键盘都有死键。事实上,您不会在键盘上找到大多数死键。例如,我猜你们中只有一小部分人(如果有的话)有死键ˉ来输入Tōkyō所需的长音符号(“变音符号”)。对于键盘上没有的那些死键,您需要寻找其他解决方案。好消息是,我们已经使用了这些技术。但这次我们要用它们来模拟死键,而不是“普通”键。因此,我们的第一个选择是使用Compose-生成长音符(键盘上的连字符减号)。按下时屏幕上不会出现任何内容,但当您按下o键时,您会看到。可以在此处找到Gtk可以在复合模式下生成的死键列表。另一种解决方法是使用Unicode字符“COMBININGMACRON”(U+0304),后跟字母o。我把细节留给你。但是,如果您好奇的话,您会注意到您输入的内容略有不同,您并不是真的在输入“带MACRON的拉丁文小写字母O”。我在最后一句话的末尾使用了大写拼写,所以这是一个提示,可以引导您找到通过Unicode组合字符以更少的键来键入ō的方法……现在我将把它留给您的聪明才智来解决。轮到你练习了!那么,你都学会了吗?这些在你的电脑上有用吗?现在轮到您来尝试了:按照上面提供的线索,稍加练习,您现在就可以完成本文开头给出的挑战。接受挑战并将结果复制到评论中作为您成功的证明。获胜没有奖励,说不定来自小伙伴们的惊喜就能满足你!