为什么我们有那么多十六进制,而实际上有足够多的字母可以使用 32 进制?

为什么我们有那么多十六进制,而实际上有足够多的字母可以使用 32 进制?

您可以将 0-255 以十六进制形式存储在 2 个字符中,因此它可以压缩数据,并用于各种事物,包括颜色、IP 和 MAC 地址。

我的问题是为什么他们只使用 16 位(或者为什么最常用的是 16 位)?字母表中有足够的字母用于 32 位,这将在相同的空间内提供 0-65536 的范围,可能允许 280 万亿种颜色,而不是只有 1600 万种。如果将字母设置为区分大小写并添加两个符号,则可以转到 64 位,允许两个字符表示最多 43 亿个值。


以下是我认为可行的一些情况示例:

IPv4 即将过时。我知道 v6 正在推出,但它太长了,很难记住。以 192.168.0.1 地址为例,它也可以存储为 C0.A8.0.1。使用 64 位十六进制,但仍将其保持在最多 8 个字符,您可以拥有 280 万亿个组合,而不是 40 亿个,我们就不会遇到这个问题。

如上所述,它还提供了更大的颜色范围。RAW 照片格式以 32 位/颜色通道记录,而不是 8 位,缺点是文件大小会大幅增加。如果 RGB 值以十六进制存储,则随着颜色范围的增加,文件大小应该不会发生变化,因为它仍然以每像素 6 位的速率存储,但基数更高。相反,它以每像素 96 位的数值记录,这是一个非常不必要的 1600% 的增加,导致照片大小超过 20MB(根据在线计算器,32 位色彩的 4K RAW 视频每秒可高达 2.5GB)。


这部分与问题无关,但我之前写过一个脚本,可以将数字转换为不同的基数,范围从二进制到 88 基数(之后符号用完了),这表明很容易实现类似的事情。例如,这是 66000 的输出。
基数 2:11111111111110000
基数 16:101D0
基数 32:20EG
基数 64:G7G
代码是这里如果有人感兴趣的话,它仍然有一些错误,而且我只在 Maya 中尝试过。有点离题,但我还注意到普通十六进制似乎比原始数字少了大约 20% 的位数,而 88 进制则减少了近 50%。


最后一个问题:有人尝试过我的想法,将照片存储为十六进制吗?如果您使用 64 位十六进制,并将照片存储为 [64;1920;Bgh54D;NgDFF4;...] 之类的数据,这有可能奏效吗?如果没有,我可能会尝试创建可以做到这一点的东西。

答案1

如果我正确理解了这个问题,你是说当你使用更大的基数时数据会“缩小”,但事实上并非如此。

以自己的例子为例: 基数 2:11111111111110000 基数 16:101D0 基数 32:20EG 基数 64:G7G

我们会使用 101D0,因为十六进制是标准的。如果我们使用 64 进制表示法会发生什么?

答案是:基本上什么都没有,因为你仍然在设备中以位的形式存储和处理数据。即使你说你有 G7G 而不是 101D0,你仍然在设备中存储和处理 11111111111110000。假设你有数字 5。如果你把它放到二进制中,它就是 101。101 有 3 位数字,5 有 1 位数字,这并不意味着 5 比 101 更压缩,因为你仍然会在计算机上将数字存储为 0101。

只是为了与您的示例保持一致,IPv6 或 MAC 地址(对于此示例,它们只是相同的东西,即由点分隔的两位数字的字符串)。

十六进制表示为 00:00:FF:01:01。这就是您通常的表达方式。这转换为二进制为 0000 0000 0000 0000 1111 1111 0000 0001 0000 0001(您现在可能开始明白我们为什么使用十六进制)。这很容易,因为 16=2^4,您可以将一个十六进制数字转换为 4 个二进制数字,然后将结果放在一起即可获得实际的二进制字符串。在您的 64 位系统中,如果我们有类似 GG:HH:01:02:03 的内容,则每个字母将转换为 6 位。

那么,这有什么问题呢?事实上,计算机内部使用 2 的幂来工作。它们并不真正关心您使用的符号。在 CPU 寄存器、内存和其他设备中,您永远不会看到以 6 位为一组的数据。

TL;DR:十六进制只是一种符号,可以帮助我们人类更容易地看到二进制的东西,因为一个字节可以表示为两个字符(0-F),无论使用什么符号读取,计算机中存储和处理的内容都是相同的。

答案2

十六进制的字面意思是 16。;)

但除了这个尖刻的答案之外,十六进制(或任何其他 2 的幂基数数字系统)只是表示二进制数据的更紧凑的格式。在最低级别,这些值仍然以数字形式表示为在最低级别上,这些位被分解成硬件架构可以轻松处理的块。

请记住,十六进制数不表示为字符 0-9 和 af——它们实际上是以位的形式存储的。 每个“数字”并不像您所建议的那样被编码为 8 位字符 0-255,其中仅使用系统中的前 16 个值。

让我们比较一下示例中的以 2 为基数和以 64 为基数的表示形式。

base2: 11111111111110000 --> 17 "digits" with 1 bit per digit = 17 bits
base64: G7G --> need 3 "digits" with 6 bits per digit = 18 bits

现在考虑一个 base64 编码,其中每个“数字”实际上由一个 8 位字符表示。您仍然有 G7G,但现在每个“数字”需要 8 位。

G7G --> 3 "digits" with 8 bits per digit --> 24 bits

即使在这个过于简单的例子中,如果你使用 base64 来表示所有内容,那么与以较小块分配空间的编号系统相比,你也会拥有更多的空闲(浪费)空间。

正如我所说,前面的例子过于简单,假设您只处理无符号数(即没有负数)。实际上,数据将存储在“字”中,其大小可能因硬件架构而异。如果您有一个 8 位字,则必须以 8 位块的形式分配值,因此 17 位值现在需要 24 位来存储。

因此,尽管使用任何 2 的幂基数计数系统(如您所建议)都很简单,但这并不常见。这可能是因为流行的现代计算机架构源自 16 位架构,其中十六进制实际上是硬件的本机语言。

答案3

十六进制似乎是二进制和十进制之间的一个很好的折衷。

  • 只需看一下就可以很容易地转换为二进制。

  • 易于阅读、书写,必要时可进行口头交流。想象一下通过电话告诉某人一个 base64 编码的字符串。

  • 70 年代和 80 年代的单板计算机曾经使用 7 段 LED,没有其他现成的显示机制。幸运的是,A、B、C、D、E 和 F 都可以在其中之一中呈现。

当然,当我们谈论 64 位、128 位和更大的数量,或者哈希之类的东西时,用十六进制、十进制或其他任何形式进行交流都不容易。对我来说,十六进制的“全盛时期”是 8 位和 16 位 CPU 普及的时候,也是低级编程更普遍的时候,因为它更有必要。我可能是错的。

我不确定十六进制除了用于表示 C/C++ 中的指针地址外是否常用。我猜十六进制在这里是出于习惯或传统而使用的,并且也成为表示某个东西是“原始二进制”值而不是任何“类型”的信号。

有人尝试过我将照片存储为十六进制的想法吗?

任何文件,无论其类型或内容如何,​​都是一大块字节。它已经是二进制的了。十六进制只是一种(非常低限度的)人性化视图。

如果您想以十六进制格式查看文件的字节,那么有很多十六进制编辑器和查看器可以做到这一点。

如果您打算将照片存储为包含十六进制数列表的文本文件,我想您可以根据需要这样做,但它会比原始文件更大且处理速度更慢。

相关内容