从四位数、UTF-8文字和灰度像素出发,说明有限状态怎样通过编码组合成数字媒体,以及位串为什么不能自己说明含义。
两种状态很少,组合却可以很多
一个开关只有开和关;四个独立开关却有16种组合。计算机把两种可区分状态抽象为0和1,称为一个比特(bit)。n个比特有2的n次方种位串:这是组合数量,不是每个位置都藏着丰富内容。
物理上不必是“完全没电”和“有电”。电路使用允许范围内可区分的电平等状态,并处理噪声、时序和可靠性。二进制是一种适合构造稳定数字逻辑的表示,不意味着现实世界本来只有两种事物。
要让位串表示数字、文字或图像,需要编码规则。表示能力来自组合和约定;理解含义则还依赖格式、上下文与解释程序。
先让位串表示一个整数
约定四位无符号二进制从左到右权重为8、4、2、1,那么1101表示8+4+0+1=13。全部四位位串可以表示0到15,总共16个值。若想表示16,必须扩展位数,或更换编码。
同样的1111,在四位无符号解释下是15,在四位二进制补码解释下是-1。这不是电路同时看见了两个数,而是解释规则不同。位宽、符号规则与字节顺序等,都是数据格式的一部分。
因此,“计算机里全是0和1,所以类型不重要”恰好说反了:正因为底层位串可以有多种解释,类型和协议才帮助我们排除错误解释。这里的补码只是反例,负数的完整运算规则留待后续。
文字不是把字形直接塞进一个数
Unicode为字符分配码点;UTF-8再把码点编码为一个或多个字节。字符A的码点为U+0041,UTF-8字节是十六进制41;“中”为U+4E2D,UTF-8字节是E4 B8 AD。[1] 十六进制只是紧凑的记数方式,每一位十六进制数对应四个比特。
这个字节序列可以手算。U+4E2D 写成 16 位二进制是 0100 1110 0010 1101;它处于 UTF-8 的三字节编码范围,采用 1110xxxx 10xxxxxx 10xxxxxx 的形式。把码点有效位分成 0100、111000、101101,填入三个位置,得到 11100100、10111000、10101101,也就是 E4 B8 AD。[4] 这里示范的是 U+4E2D,不能省略 UTF-8 对代理项、范围和最短形式的合法性约束,再把所有 16 位整数都当字符编码。
一字节通常为8位,但“一个字等于一个字节”不成立。字符、码点、编码单元以及屏幕上看到的字形并非一一对应;组合附加符号和表情序列尤其能显示这种区别。
收到E4 B8 AD之后,软件还需要知道按UTF-8解码,再由字体和排版系统绘制字形。若拿错误编码读取,位串没变,屏幕却可能乱码。Unicode的编码规则支持信息交换,不替我们决定一句话是否正确或有意义。
图像和声音怎样进入同一套表示
构造一张2×2的8位灰度图,约定按行保存四个像素,数值为0、85、170、255。像素负载是4×8=32比特,即4字节;0最暗、255最亮。真实文件还要描述尺寸、排列、颜色空间等,不能把4字节负载当作完整文件大小。
照片先经过空间采样与数值量化,保留有限个位置与有限精度。声音也可以在一系列时刻记录量化后的振幅。下面只作未压缩双声道PCM的负载算例:每秒48000次采样、每个声道每次16位,负载为48000×16×2=1536000比特/秒,即192000字节/秒。
这个算例不含容器头、元数据与压缩,也不保证采样后的声音与原始连续信号完全相同。编码能保存我们选择保留的信息,不能让有限数据无损覆盖任意连续细节。
压缩和加密改变的是什么
如果图像有大量重复或可预测结构,无损压缩可能用更少的位保存它;解压后恢复原位串。有损压缩允许丢掉某些信息,以换取更小体积。加密则依据密钥改变可读取的形式,目标也不同。
不可能让所有固定长度位串都无损压得更短:短位串的总数量不足以给每个输入分配不同输出。压缩方法利用输入的结构和分布,不会推翻这个计数事实。Shannon在1948年的论文中区分了通信工程问题与消息的语义问题。[2] 这一区分有助于避免把“信息量”直接等同于思想深度。
所以,0和1能共同承载数字媒体,并不表示所有东西都能被有限、精确地表示,也不表示机器理解了内容。真正可用的数字世界建立在位串之上的多层契约:编码、格式、程序、设备和使用语境。
一张像素图,需要的不只是四个亮度值
继续使用0、85、170、255四个字节。若约定宽2、高2、逐行存储,就形成左上最暗、右下最亮的2×2灰度图。若约定宽4、高1,同样负载变成一行;若把相同字节解释为颜色通道,又会得到别的对象。
因此,一个可交换的格式至少要交代尺寸、通道、数值精度、顺序与解释方法。像素数据像一串没有标点的数字,格式负责说明如何分组。头部或外部协议并非无用开销,而是让另一端能恢复对象的必要条件。
还要区分像素值与显示亮度。8位灰度数值只是编码,显示器的响应、色彩管理和观察环境会影响看到的光。数值128也不必自动等于人眼感觉上的“一半亮”。本例只说明编码容量,不用数值表冒充视觉质量实验。
如果把每个像素从8位减为1位,每个位置只剩两种取值,四个位置总负载降到4比特;原来的85和170就无法原样保留。体积变小来自表示空间变小,必须决定如何近似,而不是认为二进制可以无代价保留所有细节。
声音的采样率和位深,分别限制什么
采样率描述每秒取多少个样本,位深描述每个样本用多少位表示。增加采样率主要改变时间轴上的离散程度;增加位深主要改变幅值量化的等级。它们是不同维度,不能用其中一个数字代替全部音质。
前面的48kHz、16位、双声道PCM,每秒有96000个声道样本,每个2字节,因此是192000字节/秒。持续60秒,原始负载为11520000字节;按十进制MB约11.52MB,按2的20次方字节为1MiB计算,约10.99MiB。文件容器与元数据还要另外计算。
这是容量推导,不是“某音乐文件一定这么大”。压缩编码可以改变文件大小,静音也可能被不同方式表示;编码器的质量、失真目标和音源本身都相关。把码率、采样率和响度混为一谈,会误解每个数字能够支持的判断。
一个连续变化的物理波形,只有在适当信号条件、采样过程与重建条件下,才能讨论如何由离散样本恢复。这里不展开采样定理的证明,但必须保留条件;不能仅凭“比特足够多”宣称任何声音都能被有限数据精确保存。
比特翻转、压缩和意义,不能混用同一标准
若00000001中的最高位因错误变成1,按8位无符号数读取就成129;若它处在文件头,影响又可能大得多。相同数量的比特错误,对不同格式的后果并不相同。可靠传输需要检错或纠错等机制,编码能表示内容并不保证传输没有损坏。
再看压缩的计数限制:一共有256种8位输入,而长度至多7位的位串总共只有1+2+4+…+128=255种,其中还计入空串。若要求每个8位输入都能无损恢复,就无法把它们全部映射成互不相同的更短串。
现实压缩能工作,是因为某些输入更常见,或输入具有可利用的重复结构;方法可以让常见内容缩短,同时允许别的内容不缩短甚至变长。它与“任何文件都能反复压小”不是一回事。
最后,65是一个数,A是按规则读出的字符,某段文字是否有意义又是另一层。信息论中的量化对象、编码后的对象和人理解的内容,应在各自问题中使用。位串是共同的承载形式,语义来自更完整的解释关系。
一个屏幕上的“字”,为什么不一定是一个码点
字节计数、码点计数和用户看到的字符数,可能不同。例如某些带附加符号的文字既可用预组合码点表示,也可用基础字符加组合符号表示。视觉上相近,不保证底层码点序列逐字相同。
Unicode文本分割规范用扩展字素簇等规则处理用户可感知的文本边界。[3] 这不等于每一种语言和应用都只需一个字符计数函数;光标移动、字符串长度、截断与存储限制可能采用不同单位,必须明确接口。
如果把UTF-8字节数组截在一个多字节序列中间,可能得到非法编码;即使保留完整码点,也可能截断一个组合序列。正确解码、正确分割与正确显示是相连但不同的工作。
对程序接口,这些区别会直接影响字段长度与校验。要求“最多10个字符”应先解释10个字节、10个码点还是10个字素簇。把含糊需求变成具体编码契约,才让“0和1可以表示文字”成为可靠的数据交换机制。
自己检验一次解释规则
把01000001按8位无符号数读,是65;按ASCII兼容的UTF-8字节读,是A;按单通道像素强度读,是一个灰度值。同一串比特没有自己携带唯一用途。
阅读文件或接口时,先问“位宽多少、用什么编码、怎样划分边界、由谁解释”,通常比只问“里面是不是二进制”更有帮助。本篇算例是编码与计数推导,不是图像质量、音频质量或电路可靠性的实测。
来源、证据与阅读路线
- Unicode FAQ:UTF-8、UTF-16、UTF-32与编码单位;U+0041、U+4E2D为本文编码例子
- C. E. Shannon,A Mathematical Theory of Communication,1948,Introduction;大学托管原论文
- Unicode Standard Annex #29:Unicode Text Segmentation,扩展字素簇;浮动规范以文中概念说明为限
- Unicode Standard 18.0.0,Chapter 3,3.9 Unicode Encoding Forms;Table 3-6 与 3-7 的 UTF-8 位分布及合法序列
证据范围:字符编码、像素与PCM容量、有限串计数按明确假设核对;这些算例不等于显示设备、音频链路或压缩实现的实测。
写下你的评论
要发表评论,您必须先登录。