为什么英文字符比其他字母需要更少的字节表示?


31

当我在文本文件中放入“ a”时,它使它成为2个字节,但是当我放入“ա”时,它是亚美尼亚字母的一个字母,就使它成为3个字节。

电脑字母之间有什么区别?
为什么英语占用更少的空间?


22
您应该阅读StackExchange
Eric Lippert

22
我认为没有“英文字符”之类的东西。他们是罗马人。
拉斐尔2014年

5
@Raphael每个人都知道他指的是什么。但是很好。
Mathias Lykkegaard Lorenzen 2014年

1
@Raphael实际上,有很多罗马字母没有用英语使用,因此不包含在ASCII字符集中。它们中的大多数都包含修饰符,但仍需要使用修饰符来正确呈现除英语之外的各种拉丁语衍生文字中的文本。
Wutaz 2014年

7
@Raphael我认为没有“罗马人物”这样的东西。他们是拉丁人。
Blacklight Shining

Answers:


41

即将开发用于主流计算机的第一个编码方案之一是ASCII美国信息交换标准码)标准。它是在1960年代在美国开发的。

英文字母使用拉丁字母的一部分(例如,英文的重音词很少)。该字母表中有26个单独的字母,不考虑大小写。而且,在任何假装对英语字母进行编码的方案中,都必须存在单个数字和标点符号。

在1960年代,计算机还没有我们现在拥有的大量内存或磁盘空间。ASCII被开发为所有美国计算机上功能字母的标准表示形式。当时,由于当时的技术细节,决定将每个ASCII字符都设为8位(1字节)长(Wikipedia文章提到了这样的事实,穿孔的磁带一次将8位保持在一个位置上)。实际上,原始的ASCII方案可以使用7位来传输,而八位可以用于奇偶校验。后来的发展将原始的ASCII方案扩展到包括几个重音符号,数学字符和终端字符。

随着最近全球计算机使用率的增长,越来越多来自不同语言的人可以使用计算机。这意味着,对于每种语言,必须独立于其他方案开发新的编码方案,如果从不同的语言终端读取该编码方案,则会产生冲突。

通过将所有可能的有意义的字符合并为一个抽象字符集,Unicode成为了解决不同终端的方法。

UTF-8是编码Unicode字符集的一种方法。它是一种可变宽度的编码(例如,不同的字符可以具有不同的大小),并且被设计为与以前的ASCII方案向后兼容。这样,ASCII字符集将保持为一个字节大,而其他任何字符为两个或更多字节大。UTF-16是编码Unicode字符集的另一种方法。与UTF-8相比,字符被编码为一组一个或两个16位代码单元。

如评论所述,“ a”字符占用一个字节,而“ա”字符占用两个字节,表示UTF-8编码。您问题中的多余字节是由于末尾存在换行符(OP发现了此字符)。


26
没有以任何普通编码或文件格式编码文件末尾的最后一个字节。当程序读取文件时,操作系统可能会以特殊方式发出文件结尾的信号,但这是另一个问题。
Jukka K. Korpela 2014年

2
在Unicode的UTF-8版本中,ա字符为2个字节(0xD5A1);两个文件中都存在多余的字符(无论是什么字符)。 marathon-studios.com/unicode/U0561/Armenian_Small_Letter_Ayb
Dan Neely 2014年

6
@khajvah如果使用echo 'ա' > file.txt它,或使用某些编辑器编辑文件,则他们会在文件后自动添加换行符。如果运行xxd file.txt,则最后一个字节可能是0a或换行符。
丹尼尔·贝克

7
@DoktoroReichard:请在回答中说明Unicode 不是编码;而是一个抽象字符集,而UTF-16和UTF-8是Unicode代码点的编码。您答案的最后几段主要讨论UTF-8。但是,如果文件使用UTF-16,则任何代码点,即使是的代码点也a将使用两个字节(或两个的倍数)。
grawity 2014年

6
还有可能值得强调的是,“扩展的ASCII”字符集实际上根本不是ASCII,并且利用第八位的不同方式的数量使这一切变得一团糟。只需改用UTF-8。
ntoskrnl 2014年

17

1个字节为8位,因此最多可以表示256(2 ^ 8)个不同的值。

对于需要更多可能性的语言,无法维护简单的一对一映射,因此需要更多数据来存储字符。

请注意,通常,大多数编码使用ASCII字符的前7位(128个值)。剩下第8位,或者更多字符的128个值。。。加上重音符号,亚洲语言,西里尔字母等,就可以轻松理解为什么1个字节不足以保留所有字符。


所以这里实际上是解释为什么使用更多的空间,唯一的答案
费利克斯·加侬-格雷尼尔

10

在UTF-8中,ASCII字符使用一个字节,其他字符使用两个,三个或四个字节。


1
您能详细说明为什么吗?注意两种编码方法并不能完全回答问题。
MaQleod 2014年

@MaQleod创建了Unicode来替换ASCII。为了向后兼容,前128个字符相同。这128个字符可以用一个字节表示。添加了其他字节以添加其他字符。
杰森

我知道,但这是对ASCII字符有何不同的问题的答案的一部分。应该向OP解释。
MaQleod 2014年

@MaQleod也可以说Unicode联盟主要由美国公司组成,并且偏向英语字符。我认为简单的答案比主观的答案更好。
杰森

15
在UTF8中不是“用Unicode”,它只是Unicode字符集的几种编码之一。
塞巴斯蒂安·内格拉苏斯

3

一个字符所需的字节数(这个问题显然与之有关)取决于字符编码。如果使用ArmSCII编码,则每个亚美尼亚字母仅占用一个字节。不过,这不是一个好选择。

在Unicode的UTF-8传输编码中,字符需要不同数量的字节。在其中,“ a”仅占用一个字节(关于两个字节的想法有点混乱),“á”占用两个字节,亚美尼亚字母ayb“ա”也占用两个字节。三个字节一定有点混乱。相反,例如孟加拉字母“অ”在UTF-8中占用三个字节。

背景很简单,UTF-8被设计为对Ascii字符非常有效,对于欧洲和周围地区的书写系统相当有效,而其余所有效率都较低。这意味着基本的拉丁字母(英语文本主要由拉丁字母组成),一个字符只需要一个字节;对于希腊语,西里尔字母,亚美尼亚语和其他一些语言,需要两个字节;所有其他都需要更多。

UTF-8还具有(如在评论中指出的)有用的属性,即Ascii数据(以8位单元表示,这在很长一段时间以来几乎一直是唯一的方法)也被琐碎地UTF-8编码了。


谢谢你的回答。其他字节是因为我使用的程序自动在末尾添加了换行符。
khajvah 2014年

1
我认为UTF-8并不是为了提高 ASCII数据的效率而设计的,而是为了兼容性。UTF-8具有非常好的特性,即7位ASCII内容(高位设置为零)与编码为UTF-8的相同内容相同,因此对于通常处理ASCII的工具,它是一种替代品。据我所知,没有其他Unicode编码方案具有该属性。UTF-8对于大多数数据也相当紧凑,特别是如果您处于Unicode BMP领域之内。
2014年

1
@MichaelKjörling,我添加了对该功能的引用。但是,在早期,对Unicode的主要反对意见是效率低下,而UTF-16将数据大小(主要是Ascii)增加了一倍。UTF-8意味着,例如对于英文文本,您只需为使用的非Ascii字符“付费”。
Jukka K. Korpela 2014年

3

1960年代(及以后)的字符代码是特定于机器的。在1980年代,我短暂地使用了DEC 2020机器,该机器具有36位字,每个字符编码有5、6和8(IIRC)位。在此之前,我将IBM 370系列与EBCDIC一起使用。具有7位的ASCII进行了排序,但是与使用全部8位表示额外字符的IBM PC“代码页”一团糟,例如用于绘制原始菜单的各种盒式绘图和后来的Latin-1(8位)编码,前7位为ASCII,另一半为“国家字符”,如ñÇ或其他,最流行的可能是Latin-1,它是使用拉丁字符(以及重音符号和变体)针对英语和大多数欧洲语言量身定制的。

编写混合文本(例如英语和西班牙语)效果很好(只使用Latin-1,这两个语言的超集),但是混合使用不同编码的任何内容(例如,包括希腊或俄罗斯的片段,更不用说日语的亚洲语言了)一场真正的噩梦。最糟糕的是,俄语(尤其是日语和中文)具有几种流行的,完全不兼容的编码。

今天,我们使用Unicode,它被编码为支持英文字符的有效编码(例如UTF-8)(令人惊讶的是,英文字母的编码恰好对应于ASCII),因此使许多非英文字符使用更长的编码。


2

Windows 8.1美国/英语文件,带有一个“ a”的记事本保存。

  • 保存为ANSI 1字节
  • 保存AS Unicode 4字节
  • 保存为AS UTF-8 4字节

用记事本保存的带有单个“ա”的文件

  • 无法保存AS ANSI
  • 保存AS Unicode 4字节
  • 保存为UTF-8 AS 5字节

单个“ a”在ANSI中被编码为单个字节,在Unicode中,每个字符通常为2个字节,文件的开头还有2个字节的BOM(字节顺序标记)。UTF-8具有3字节的BOM表和单字节字符。

对于“ա”,该字符在ANSI字符集中不存在,因此无法保存在我的机器上。Unicode文件与以前相同,并且UTF-8文件大1个字节,因为字符占用2个字节。

如果您的计算机来自其他地区,则可能安装了不同的OEM代码页,其中包含ASCII范围内255个字符的不同字形。正如@ntoskrnl提到的那样,我的计算机的OEM代码页为Windows-1252,这是美国英语的默认代码。


4
记事本(通常是Windows)在这里使用令人困惑的术语。“ ANSI”是与语言环境相关的单字节编码(英语版本为Windows-1252),“ Unicode”是UTF-16。
ntoskrnl 2014年

@ntoskrnl没错,但是如果您在下拉列表中进行编码,它会显示ANSI,这就是为什么我提到如果您使用不同的OEM代码页可能会得到不同的结果。
Darryl Braaten 2014年

2

如果您对字符的存储方式感兴趣,可以访问www.unicode.org并四处看看。它们的主页顶部是一个“代码图表”链接,它向您显示Unicode中可用的所有字符代码。

总而言之,Unicode中有超过一百万种可用代码(并非全部使用)。一个字节可以容纳256个不同的值,因此,如果要存储所有可能的Unicode代码,则需要三个字节。

取而代之的是,Unicode通常以“ UTF-8”编码存储,其中某些字符使用较少的字节,而另一些字符使用较多的字节。前128个代码值存储在单个字节中,前2048个代码值存储在两个字节中,最多65536个存储在三个字节中,其余占四个字节。这样做的目的是使经常使用的代码值占用更少的空间。AZ,az,0-9和!@ $%^&*()-[} {};':“ |,。/ <> ?,有些我忘了一个字节;几乎所有英语,占98%可以将德语和法语(仅作猜测)存储在每个字符一个字节中,而这些字符是最常用的字符。 ,韩文,泰文,大量的数学符号,每个字符可以写三个字节。稀有的东西(如果您想用线性A或线性B,Emojis写文本)需要四个字节。

另一种编码是UTF-16。在UTF-8中占用1、2或3个字节的所有内容在UTF-16中都占用两个字节。如果您的中文或日语文本之间的拉丁字符很少,那么这是一个优势。

关于UTF-8设计的原因:与其他设计相比,它具有多个优点。他们是:

与US-ASCII字符的兼容性

合理的紧凑性

自同步:这意味着如果给定字节序列的一部分(采用UTF-8编码的字符),则可以找出字符的起始位置。在某些编码中,xy和yx都可能是字符的有效编码,因此如果给定了序列的一部分... xyxyxyxyxyxyxy ...您将不知道自己拥有哪些字符。

排序正确性:如果按字节值对包含UTF-8编码字符的字符串进行排序,则会根据其Unicode值对它们进行自动正确排序。

与单字节代码兼容:大多数假定单字节值的代码都可以自动正确地与UTF-8编码字符一起使用。

再加上我忘记的任何原因。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.