字节和字符之间有什么区别(至少*nixwise)?

字节和字符之间有什么区别(至少*nixwise)?

我知道任何字符都由一个或多个字节组成。

如果我没记错的话,至少在 *nix 操作系统中,一个字符通常(或完全?)仅由一个字节组成。

字节和字符之间有什么区别(至少*nixwise)?

答案1

POSIXly,强调我的:

3.87 字符
序列一个或多个字节代表单个图形符号或控制代码。

实际上,确切的含义取决于有效的语言环境,例如在“C”语言环境下,printf '\xc3\xa4\xc3\xb6' |wc -m给出 4,因为它有效地计算字节;而在 UTF-8 语言环境下则给出 2,因为这是两个 UTF-8 编码的字符äö。假设您的终端也设置为 UTF-8,您当然可以只写printf 'äö'.

(请注意,它wc -c被定义为计算字节数,而不是字符数,这很容易令人困惑。)

更糟糕的是,字符支持还取决于实用程序,并不是所有东西都能干净地处理多字节字符(更不用说 Unicode 的所有怪癖了)。例如,GNU tr 处理字节,无论其手册页内容如何:

$ printf ä | tr ä xy; echo
xx
$ printf ö | tr ä xy; echo
x�

第一个与 相同tr '\303\244' 'xy',因此 的两个字节都ä被替换,而第二个发生是因为两者 的第一个字节ä相同ö。当然,如果它真的处理字符,那些应该打印xö

答案2

按照惯例,一个字节是POSIX 定义八位。位是二进制数字(即基本数字10几乎所有数字计算的基础)。

一个字符是经常一个字节并且在某些上下文中(例如ASCII)可以被定义为一个字节长度。然而,Unicode、UTF-8 和 UTF-16 定义了扩展字符集,其中单个字符(或字形)可以由长度超过一个字节的数据有效负载定义。

单个字符:

Q̴̢̪̘̳̣̞̩̪̑̍̉̆̉͛̑̂̕͝

是单个字符,但它是通过将多个重音符号(或变音符号)应用于基本字形(简单的Q.这种编码的字节数比长度多得多:仅将该字符放入文件中并使用hexdump而不是cat在我的区域设置上显示内容会产生:

$ hexdump -C demo
00000000  51 cc b4 cc 91 cc 8d cc  89 cc 86 cc 89 cd 9d cd  |Q...............|
00000010  9b cc 91 cc 95 cc 82 cc  aa cc 98 cc b3 cc a3 cc  |................|
00000020  a2 cc 9e cc a9 cc aa 0a                           |........|
00000028

答案3

A字节是基本元素,通常为 8 位长(也称为八位位组),尽管已经有(并且可能仍然有)其他尺寸。使用 8 位字节,可以编码 256 个不同的值(从 0 到 255)。

对于字符,情况因所使用的编码和字符集而异。

  • 最简单最常见的编码/字符集是ASCII码。每个角色都使用一字节(实际上更少,只有7位)。它包括不带变音符号(重音符号等)的英文字母的小写和大写字母、数字、常用标点符号和控制字符。

  • 然后我们就有了一系列 8 位字符集,例如ISO-8859系列、MS-DOS 和 Windows代码页,Mac 字符集, ETC。

    这些是 ASCII 的超集(前 128 个值与 ASCII 相同),另外 128 个值用于特定于区域设置的字符(重音字符、替代脚本,例如希腊语或西里尔语...)。

    在计算机之间甚至程序之间传输文件时,这会引起各种麻烦,因为并非所有计算机都使用相同的字符集。

    在这种情况下,仍然有一个角色一字节

  • 然后是统一码family,它试图将所有内容统一在一个集合中,该集合显然大于 256,因此无法容纳单个字节。

  • 起初,人们认为 16 位就足够了,于是设计了 UCS-2,使用2字节每个字符(这意味着最多 65536 个可能的字符,尽管并未分配所有字符,这允许 UTF-16)。

  • 然后很明显 2 个字节并不总是足够,因此引入了 UTF-16,它使用代理对对附加字符进行编码。对于BMP(基本多语言平面)中的字符,他们仍然使用2字节确切地说,但对于“额外”字符,它们使用 2 个代码单元,每个代码单元 2 个字节,总共4字节

    UTF-16 是 Windows NT 及其后续版本的本机编码。然而,即使 UTF-16 也存在问题,因为并非每个人都同意两个字节的顺序:小端或大端,所以我们有 UTF-16LE 和 UTF-16BE。有或没有 BOM。

  • 还有 UCS-4 和 UTF-32 使用4字节每个字符(UTF-32 仅限于可以表示为 UTF-16 的值),但这种情况非常罕见。

  • UTF-8 是一种可变长度编码,可能正在成为最常见的编码。字符可以编码为任何地方1 到 4 个字节之间

    UTF-8 的天才之处在于 Unicode 的 ASCII 部分(代码点 0 到 127)仍然被编码为单个字节,并且保证超出该范围的代码点永远不会包含 0 到 127 之间的字节。这允许一定程度的与具有特殊含义的特定字符的软件兼容,包括路径的/(或\:)、编程语言和 shell 的大量标点符号(!=+-*/^"'<>[]{}等)、控制字符(例如 CR、LF 或制表符、空格等)。

但在 Unicode 中,还有一个额外的复杂性:代码点可以组合。您可以编码é为单个字符é(U+00E9 LATIN SMALL LETTER E AND ACUTE),或编码为e(U+0065 LATIN SMALL LETTER E) 后跟◌́(U+0301 COMBINING ACUTE ACCENT)。如图所示多普戈蒂的回答,您可以在一个字母上堆叠相当多的组合标记!

变音符号并不是唯一的组合代码点。有很多用于制作变体,尤其是表情符号。你可以改变他们的肤色(

相关内容