为什么存在不同的编码类型?

20

这是一个初学者的问题,但我想知道为什么会有不同的编码类型,以及它们之间的区别(例如ASCII,utf-8和16,base64等)。

3个回答

18

我相信原因有很多,但主要问题是:“您需要显示(编码)多少个字符?”例如,如果您住在美国,可以使用ASCII。但在许多国家,我们需要像ä、å、ü等字符。(如果SO仅支持ASCII编码或者您尝试将此文本作为ASCII编码的文本阅读,则在ä、å和ü的位置上会看到一些奇怪的字符。)还要考虑中国、日本、泰国和其他“异国情调”的国家。您可能在世界各地看到的照片上的奇怪符号可能只是字母,而不是漂亮的图片。

至于不同编码类型之间的区别,您需要查看它们的规范。这里是UTF-8的一些信息。

我不熟悉UTF-16。这里是一些关于它们之间差异的信息。

当需要编码二进制数据以在设计用于处理文本数据的介质上存储和传输时,使用Base64。如果您曾经使用PHP创建过某种类型的电子邮件系统,您可能已经遇到过Base64。

  • http://www.phpeveryday.com/articles/PHP-Email-Using-Embedded-Images-in-HTML-Email-P113.html
  • 这篇文章介绍如何在HTML电子邮件中使用嵌入式图像,并提供了PHP代码示例。通过将图像直接嵌入到电子邮件中,而不是作为外部链接引用,可以增强邮件的可读性和吸引力。

    简而言之:支持计算机程序用户界面本地化到多种不同语言。(编程语言仍然主要由ASCII编码中的字符组成,虽然例如在Java中可以使用UTF-8编码来命名变量,并且源代码文件通常存储为其他编码的文本,例如UTF-8编码。)

    简而言之(第二部分):当不同的人从特定的角度(甚至没有观点,如果可能的话)尝试解决某些问题时,结果可能会有很大的不同。Joel在他的unicode文章中引用了以下内容(下面有链接):“因为字节有多达八个位,许多人开始思考:‘天哪,我们可以使用代码128-255来达到我们自己的目的。'问题在于,许多人同时想到了这个主意,并且他们对128到255之间的空间中应该放什么有自己的想法。”

    感谢Joachim和tchrist提供的所有信息和讨论。这里有两篇文章我刚读过。(链接都在我之前提供的那个页面上。)自几年前我最后一次阅读Joel的文章以来,我已经忘记了大部分内容。希望这是一个不错的主题介绍。Mark Davis深入探讨了这个话题。


    3
    抱歉,这个答案中有太多不正确的部分:UTF-16不能表示比UTF-8更多的字符,因为它们都可以表示所有Unicode字符。在Java源代码中,ASCII很少被使用,更常见的是UTF-8或某些ISO-8859-*变种(即使它通常不会有任何区别,因为代码只包含ASCII可编码字符)。还应该注意的是,Base64根本不是字符编码!它是一种以文本形式表示二进制数据的方式。 - Joachim Sauer
    @Joachim感谢您的建议。我修改了我的回答。不确定如何解释您评论中的Java部分。我的意思是(并认为我已经写下)源代码是ASCII(保留字,函数名称,语言结构),但文件本身则是其他东西。例如,我的PHP文件使用UTF-8编码,但HTML标签和PHP代码由ASCII字符组成。这不包括即输出的字符串和其他可供最终用户看见的文本(这就是我需要首先使用UTF-8的原因)。请进一步评论以进行改进。 - ZZ-bb
    Java将其语言规范中使用的字符和符号限制为ASCII可表示的那些。但这并不意味着Java源代码自动成为ASCII文本。它只意味着它可以用ASCII编码。 - Joachim Sauer
    1
    我个人不喜欢将“ASCII”这个术语(稍微有些懒散)用来指代“仅限于ASCII可编码字符的文本”。作为一种文本编码方式,ASCII现在已经变得非常不重要了,但是它仍然被频繁引用,除了作为不学习当今实际使用的编码方式的借口之外,没有任何真正的理由。 - Joachim Sauer
    1
    @Joachim 再次感谢。希望我已经把所有的粗糙之处都编辑掉了。这样就足以让 -1 消失了吗?还是我应该放弃尝试?我必须承认,你在这个领域的知识远远超过我,但我希望我的帖子中最后的错误已经被编辑掉了。 - ZZ-bb
    显示剩余2条评论

    11
    真正的原因是Unicode联盟太晚出现了,导致现在有这么多变体。
    早期,内存和存储都非常昂贵,并且使用超过8(或有时仅为7)比特来存储单个字符被认为是过度浪费。因此,几乎所有文本都是使用7或8位每个字符来存储的。显然,8位比特不足以表示所有人类语言中的字符。它只能表示单个语言中使用的大多数字符(甚至对于某些语言来说,这也不可能)。因此,设计了许多不同的字符编码,允许不同的语言(英语、德语、希腊语、俄语等)用8位每个字符来编码他们自己的文本。毕竟,一个文本文件(通常甚至一个计算机系统)只会用于单一的语言,对吗?
    这导致了一个局面,即没有任何一种字符到数字的映射得到单一的认可。出现了许多不兼容的解决方案,也没有真正的中央控制。一些计算机系统使用ASCII,另一些使用EBCDIC(或更确切地说是EBCDIC的众多变体之一),ISO-8859-*(或其许多派生版本)或其他大量几乎不为人知的编码。

    最终,Unicode联盟站出来承担起了这个任务,制定了这个单一映射(以及大量的有用但超出本答案范围的辅助数据)。

    当Unicode联盟最终制定了一个相当全面的计算机可能表示的字符列表(以及许多编码方案,根据您具体的需求将它们编码为二进制数据),其他字符编码方案已经被广泛使用。这极大地减缓了Unicode及其编码(UTF-8、UTF-16)的采用速度。

    现在,如果您想表示文本,最好使用几种可以表示所有Unicode字符的编码之一。UTF-8和UTF-16结合起来应该足以满足99%的所有用例,UTF-32覆盖了几乎所有其他用例。并且要明确一点:所有UTF-*编码都可以编码所有有效的Unicode字符。但是,由于UTF-8和UTF-16是可变宽度编码,它们可能不适合所有用例。除非您需要与无法处理这些编码的旧系统进行交互,否则现在很少有理由选择其他编码。

    1
    这是不正确的。UTF-{8,16,32}中的所有三种编码都可以精确地表示100.00%的所有合法Unicode标量值。UTF-16无法表示代理项,因为它们不是合法的Unicode标量值。UTF-{8,32}算法可以表示这些值,但在这些编码中,明确禁止出现这些值。这保证了所有合法的代码点都可以在UTF-{8,16,32}中自由交换。 - tchrist
    1
    @tchrist:我并不是想说UTF-32可以以某种方式表示更多的字符,而是在某些用例中,它的固定宽度属性是必要的(例如,如果您绝对需要对Unicode字符串进行* O(1)索引*)。 在这些情况下,UTF-32是一个好的解决方案,而UTF-8和UTF-16则不足够。 - Joachim Sauer

    3
    主要原因是为了能够显示更多字符。当互联网处于萌芽期时,没有人真正考虑到有一天会有来自世界各地的所有国家和语言的人使用它。因此,一个小的字符集就足够了。逐渐地,它被证明是有限制的和以英语为中心的,因此需要更大的字符集。

    啊,只是为了支持其他语言的字符,谢谢。 - Coola
    1
    我会说“计算机使用”而不是“互联网”。人们想要在他们的母语中使用计算机程序(Word、Photoshop、Thunderbird等)。我编辑了我的答案(再次)以强调本地化的重点。 - ZZ-bb
    2
    @Coola 你所写的完全是错误的。Unicode 不仅仅涉及“非英语”字符。它包括许多专业字符,由排版工人和校对员、数学家和物理学家、语言学家和词典编纂者使用 —— 即使在100% 的英文文本中也是如此。 - tchrist

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接