Encoding 什么是字符编码?我为什么要麻烦它

Encoding 什么是字符编码?我为什么要麻烦它,encoding,character-encoding,Encoding,Character Encoding,我对字符编码的概念很困惑 什么是Unicode、GBK等?编程语言如何使用它们 我需要费心去了解他们吗?有没有一种更简单或更快的编程方法,而不必为它们操心呢?(注意,为了更简单的解释,我松散地/通俗地使用了其中的一些术语,但仍然抓住了要点。) 一个字节只能有256个不同的值,即8位 由于字符集中有超过256个字符的字符集,一般不能简单地说每个字符都是一个字节 因此,必须有描述如何将字符集中的每个字符转换为字节序列的映射。某些字符可能映射到单个字节,但其他字符必须映射到多个字节 这些映射是编码,因

我对字符编码的概念很困惑

什么是Unicode、GBK等?编程语言如何使用它们

我需要费心去了解他们吗?有没有一种更简单或更快的编程方法,而不必为它们操心呢?

(注意,为了更简单的解释,我松散地/通俗地使用了其中的一些术语,但仍然抓住了要点。)

一个字节只能有256个不同的值,即8位

由于字符集中有超过256个字符的字符集,一般不能简单地说每个字符都是一个字节

因此,必须有描述如何将字符集中的每个字符转换为字节序列的映射。某些字符可能映射到单个字节,但其他字符必须映射到多个字节

这些映射是编码,因为它们告诉您如何将字符编码为字节序列


至于Unicode,在非常高的级别上,Unicode是一种尝试,为每个字符分配一个唯一的数字。显然,这个数字必须比一个字节宽一些,因为有256个以上的字符:)Java使用Unicode版本,其中每个字符都被分配一个16位的值(这就是为什么Java字符是16位宽的,并且具有从0到65535的整数值)。当您获得Java字符的字节表示形式时,您必须告诉JVM您要使用的编码,以便JVM知道如何为字符选择字节序列。

字符编码是用来解决为使用不同语言的人编写软件的问题

你不知道这些字符是什么,它们是如何排列的。因此,您不知道这种新语言中的字符串在二进制中是什么样子,坦率地说,您不在乎

你所拥有的是一种将字符串从你所说的语言翻译成他们所说的语言的方法(比如翻译)。您现在需要一个能够以二进制表示两种语言而不发生冲突的系统。编码就是那个系统

它允许您编写软件,无论语言以二进制形式表示。

ASCII是最基本的 最初,1个字符始终存储为1字节。一个字节(8位)有可能区分256个可能的值。但事实上,只使用了前7位。所以只定义了128个字符。此集合称为ASCII字符集

  • 0x00
    -
    0x1F
    包含转向代码(例如CR、LF、STX、ETX、EOT、BEL等)
  • 0x20
    -
    0x40
    包含数字和标点符号
  • 0x41
    -
    0x7F
    主要包含字母字符
  • 0x80
    -
    0xFF
    第8位=未定义
法语、德语和许多其他语言需要额外的字符。(例如,
a,é,ç,ô,…
)在ASCII字符集中不可用。所以他们用第8位来定义他们的角色。这就是所谓的“扩展ASCII

问题是,额外的1位容量不足以覆盖世界上所有语言。因此,每个区域都有自己的ASCII变量。有许多扩展ASCII编码(
latin-1
是一种非常流行的编码)

流行问题:“ASCII是字符集还是编码”<代码>ASCII是一个字符集。然而,在编程中,
charset
encoding
被广泛用作同义词。如果我想引用一种只包含ASCII字符的编码(第8位总是0):那就是
US-ASCII

Unicode更进一步 是字符集的一个很好的例子,而不是编码。它使用与ASCII标准相同的字符,但它使用附加字符扩展列表,从而为每个字符提供一个
u+xxxx
格式的代码点。它希望包含全世界使用的所有字符(和流行图标)

UTF-8、UTF-16和UTF-32是应用Unicode字符表的编码。但它们在编码方式上都略有不同。UTF-8在编码ASCII字符时仅使用1字节,输出与任何其他ASCII编码相同。但对于其他字符,它将使用第一位指示后面将有第二个字节

是一种编码,就像UTF-8使用多个字节一样。原理基本相同。第一个字节遵循ASCII标准,因此仅使用7位。但就像UTF-8一样,第8位可以用来表示第2个字节的存在,然后用第2个字节对22000个汉字中的一个进行编码。主要区别在于,它不遵循Unicode字符集,相反,它使用一些中文字符集

解码数据 当您对数据进行编码时,您使用了编码,但当您解码数据时,您需要知道使用了什么编码,并使用相同的编码对其进行解码

不幸的是,编码并不总是声明或指定的。如果所有文件都包含一个前缀来指示它们的数据存储在什么编码中,那么这将是理想的选择。但在许多情况下,应用程序只需假设或猜测应该使用什么编码。(例如,他们使用操作系统的标准编码)

对此仍然缺乏认识,因为许多开发人员甚至不知道编码是什么。

Mime类型 Mime类型有时与编码混淆。它们是接收器识别到达的数据类型的有用方法。下面是一个HTTP协议如何定义其功能的示例
Content-Type: text/html; charset=utf-8
// the -1 indicates that there is no data
int input = stream.read();
if (input == -1) throw new EOFException();

// bytes must be made positive first.
byte myByte = (byte) input;
int unsignedInteger = myByte & 0xFF;
char ascii = (char)(unsignedInteger);
// wrap your stream in a reader. 
// specify the encoding
// The reader will decode the data for you
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);