编码和字符集有什么区别?


151

我对文本编码和字符集感到困惑。由于许多原因,我在接下来的工作中必须学习非Unicode,非UTF8的知识。

我在电子邮件标头中找到了“ charset”一词,就像在“ ISO-2022-JP”中那样,但是在文本编辑器中没有这样的编码。(我环顾了不同的文本编辑器。)

文本编码和字符集有什么区别?如果您可以向我展示一些用例示例,我将不胜感激。


Answers:


144

基本上:

  1. 字符集是可以使用的字符集
  2. 编码是这些字符存储到内存中的方式

42
是的,但是在实际使用中,“字符集”通常指字符库又指编码方案。
艾伦·摩尔

@AlanMoore确实,人们说“十进制数”几乎就是用“十进制分隔符”来指代任何数字。这不是真的正确,但是是的,您应该意识到有些人是这样使用它的。
bvdb

2
那是不对的。例如,Unicode表示字符集,但是有多种可能的编码(UTF-8,UTF-16,UTF-32)。
rghome

84

每种编码都有与之关联的特定字符集,但是给定字符集可以有多个编码。字符集就是听起来像的一组字符。有很多字符集,包括许多专用于特定脚本或语言的字符集。

但是,我们在向Unicode过渡的过程中进展顺利,其中包括一个能够代表几乎所有世界脚本的字符集。但是,Unicode有多种编码。编码是将字符串字符串映射为字节字符串的一种方式。Unicode编码的示例包括UTF-8UTF-16 BEUTF-16 LE。对于特定的应用程序或机器体系结构,每种方法都有其优势。


20
请注意,javadoc错误地使用“字符集”而不是“编码”,例如在InputStreamReader中,我们读到“ InputStreamReader是从字节流到字符流的桥梁:它读取字节并使用指定的字符集将它们解码为字符。它使用的名称可以指定,也可以明确指定,也可以接受平台的默认字符集。” 。但是,它们的意思是“编码”。
David Tonhofer 2014年

4
感谢您的解释。Unicode是一个字符集,而UTF-8Unicode的一种编码方式,而UTF-16Unicode的另一种编码方式。
HongchaoZhang

47

除了其他答案外,我认为这篇文章也是不错的阅读 http://www.joelonsoftware.com/articles/Unicode.html

这篇文章的标题是Joel Spolsky撰写绝对是每个软件开发人员的绝对最低限度,肯定是他们必须完全了解Unicode和字符集(无借口!) ” 。这篇文章已有10多年的历史了,但是(不幸的是)内容仍然有效...


2
非常感谢您介绍本文。这一个很好的。
传统知识。

9
通过简短解释为什么我应该阅读Joel的文章,可以改善此答案。
james.garriss

@mattanja您提供的链接非常棒。感谢分享。投票了。
hagrawal

1
我也想写这篇很棒的文章,是乔尔·斯波斯基(Joel Spolsky)的附录。kunststube.net/encoding
mkb

初读时我听不懂乔尔的文章。相反,我发现此PowerPoint更加清晰具体:unicode.org/notes/tn23/Muller-Slides+Narr.pdf
johnsimer '16

27

字符编码包括:

  1. 支持的字符集
  2. 字符和整数(“代码点”)之间的映射
  3. 如何将代码点编码为一系列“代码单元”(例如,用于UTF-16的16位单元)
  4. 代码单元如何编码为字节(例如,大端或小端)

步骤#1本身就是一个“字符库”或抽象的“字符集”,而#1 +#2 =一个“编码字符集”。

但是在Unicode流行之前,每个人(东亚除外)都使用单字节编码,第3步和第4步很简单(代码点=代码单位=字节)。因此,较旧的协议没有明确区分“字符编码”和“编码字符集”。较旧的协议charset在真正表示编码时使用。


这就是为什么我们可以在html META标记中读取charset ='utf-8'吗?因为它是很久以前定义的
Eildosa

26

希望为以后访问的人们提供更多的机会,希望对您有所帮助。


字符集

每种语言都有字符,这些字符的集合构成该语言的“字符集”。对字符进行编码后,会为其分配一个唯一的标识符或一个称为代码点的数字。在计算机中,这些代码点将由一个或多个字节表示。

字符集示例: ASCII(覆盖所有英文字符),ISO / IEC646,Unicode(覆盖世界上所有活泼语言的字符)

编码字符集

编码字符集是为每个字符分配唯一编号的集合。该唯一编号称为“代码点”。
编码字符集有时称为代码页。

编码方式

编码是一种将代码点映射到一些字节的机制,以便可以使用相同的编码方案在不同的系统上均匀地读写字符。

编码示例: ASCII,Unicode编码方案,例如UTF-8,UTF-16,UTF-32。

以上3个概念的阐述

  • 考虑这一点-Devanagari 字符集中的字符“क” 具有十进制代码点 2325,09 15使用UTF-16编码时将由两个字节()表示
  • 在“ ISO-8859-1”编码方案中,“ü”(拉丁字符集中只是一个字符)表示为十六进制值,FC而在“ UTF-8”中则表示为,C3 BC而在UTF-16中表示为FE FF 00 FC
  • 不同的编码方案可能使用相同的代码点表示不同的字符,例如,在“ ISO-8859-1”(也称为Latin1)中,字母“é”的十进制代码点值为233。但是,在ISO 8859-5中,相同的代码点代表西里尔字母'щ'。
  • 另一方面,Unicode字符集中的单个代码点实际上可以映射到不同的字节序列,具体取决于用于文档的编码。使用代码点2325(十六进制表示为915)的梵文字符scal,在使用UTF-16编码(09 15)时将由两个字节表示,对于UTF-8(E0 A4 95)将由三个字节表示,而对于UTF-32 将由四个字节表示(00 00 09 15

11

字符集或字符库仅仅是字符集(无序集合)。编码字符集为曲目中的每个字符分配一个整数(“代码点”)。编码是将代码点明确表示为字节流的一种方式。


这应该是公认的答案。它明确定义了三个概念:字符集,编码字符集和编码。
马库斯·朱尼乌斯·布鲁图斯

6

用谷歌搜索。 http://en.wikipedia.org/wiki/Character_encoding

差异似乎很细微。字符集一词实际上不适用于Unicode。Unicode经历了一系列抽象。抽象字符->代码点->代码点的编码为字节。

字符集实际上跳过了这一步,直接从字符跳到字节。字节序列<->字符序列

简而言之,编码:代码点->字节字符集:字符->字节


5

一个字符集只是一个集合。它要么包含例如欧元符号,要么不包含。就这样。

编码是从字符集到整数集的双射映射。如果支持欧元符号,则必须为该字符分配一个特定的整数,而不能分配其他整数。


它必须是双射的吗?
约尔格W¯¯米塔格

2
好吧,编码和解码应该是确定性的,因此确实不会有任何歧义的映射。我想您可能有一组不连续的整数作为共域,但是当您存储文本时这会浪费空间,并且工程师讨厌浪费空间。
Kilian Foth 2010年

1
传统字符编码通常不是双射的。例如,在IBM437中,ß和β均由0xE1表示。
dan04

3

在我看来,字符集是编码(组件)的一部分,编码具有字符集属性,因此可以在许多编码中使用字符集。例如,unicode是用于UTF-8,UTF-16等编码的字符集。请参见此处的插图:看到这里的插图

charset中的char并不表示编程环境中的char类型,它表示现实世界中的char类型,在英语中可能相同,但是在其他语言中,例如中文,“我”在charset中是不可分割的“ char” (UNICODE,GB [用于GBK和GB2312]),“ a”也是字符集(ASCII,ISO-8859和UNICODE)中的一个字符。


1

在我看来,“字符集”一词应仅限于标识HTTP,MIME和类似标准中使用的参数,以按名称指定字符编码(从一系列文本字符到字节序列的映射)。例如:charset=utf-8

不过,我知道MySQL,Java和其他地方可能使用“字符集”一词来表示字符编码。


1

编码是字符集中字节和字符之间的映射,因此,讨论和理解字节字符之间的区别将很有帮助。

可以将字节视为介于0到255之间的数字,而字符是抽象的东西,例如“ a”,“ 1”,“ $”和“Ä”。可用的所有字符集称为字符集

每个字符都有一个或多个用于表示它的字节序列。但是,字节的确切数量和值取决于所使用的编码,并且有许多不同的编码。

大多数编码基于旧字符集和称为ASCII的编码,ASCII是每个字符一个字节(实际上只有7位),包含128个字符,其中包括许多美国英语中常用的字符。

例如,这是ASCII字符集中的6个字符,由值60到65表示。

Extract of ASCII Table 60-65
╔══════╦══════════════╗
║ Byte ║  Character   ║
╠══════╬══════════════║
║  60  ║      <       ║
║  61  ║      =       ║
║  62  ║      >       ║
║  63  ║      ?       ║
║  64  ║      @       ║
║  65  ║      A       ║
╚══════╩══════════════╝

在完整的ASCII集中,使用的最小值是0,最大值是127(这两个都是隐藏的控制字符)。

但是,一旦您开始需要比基本ASCII所提供的字符更多的字符(例如,带有重音符号的字母,货币符号,图形符号等),则ASCII不适合,并且您需要更广泛的内容。您需要更多的字符(不同的字符集),并且需要不同的编码,因为128个字符不足以容纳所有字符。某些编码提供一个字节(256个字符)或最多六个字节。

随着时间的流逝,已经创建了许多编码。在Windows世界中,有CP1252或ISO-8859-1,而Linux用户倾向于使用UTF-8。Java本机使用UTF-16。

一个编码中一个字符的一个字节值序列可能代表另一编码中一个完全不同的字符,甚至可能无效。

例如,在ISO 8859-1中â由一个字节的value表示226,而在UTF-8中则由两个字节表示:195, 162。但是,在ISO 8859-1中195, 162将是两个字符Ã,¢

当计算机在内部存储有关字符的数据或将其传输到另一个系统时,它们将存储或发送字节。想象系统打开文件或接收消息时看到字节195, 162。它怎么知道这些是什么字符?

为了使系统将这些字节解释为实际字符(并显示它们或将其转换为另一种编码),它需要知道所使用的编码。这就是为什么编码出现在XML标头中或可以在文本编辑器中指定的原因。它告诉系统字节和字符之间的映射。

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.