跳到正文
参考文档 / ZLIB × LEAN

校验和

此页源文件快照 · 57ad356e10ec68ee · 对应提交的原文 ↗

API 手册 · 契约约定 · 缓冲区工具

逐块计算缓冲区的校验和,或合并独立处理的字节序列的校验和,而不重新读取数据。 下文的字节序列 A 和 B 是普通数据;契约使用这些序列的 Adler-32 或 CRC-32。例如先处理 A,再处理 B,可以把 A 的校验和作为下一次更新的起始值;若 A、B 已在不同位置独立处理,也可以用组合接口得到 A 后接 B 的校验和。

更新函数里的 buf 指向这一批输入,len 是这一批的字节数,传入的 adler 或 crc 是继续计算的起始值。组合函数里的 len2 则只表示后一段 B 的字节数,不是两段总长度。

任务 入口
更新 Adler-32 大小类型长度、32 位长度
合并 Adler-32 普通偏移类型、显式 64 位偏移类型
更新 CRC-32 大小类型长度、32 位长度
合并 CRC-32 普通偏移类型、显式 64 位偏移类型
复用 CRC 合并算子 生成、用 64 位长度生成、应用
查看字节表 get_crc_table

这些聚焦契约对应固定版本源码及登记补丁,在默认 LP64 Linux 静态构建下的 adler32.c、crc32.c 和 zlib.h。 所有校验和入口都不写入状态、不分配或释放内存,也不执行 I/O。 特殊数值结果是普通值,而不是错误码。定义域和效果互相独立,见契约约定。 超出聚焦前提只表示本契约不作保证,不自动等于 C 未定义行为(UB),也不保证一定返回错误码。

实用校验和契约使用真实字节序列 A 和 B。各校验和独立计算:Adler-32 从 1 开始, CRC-32 从 0 开始。这些契约有意不对伪造校验和值作功能保证。 Lean 目标还描述任意种子及精确标量结果。 Adler 入口及其 Lean 目标都要求 NULL 初始化查询的长度为零。 见范围偏差和公开目标。

此构建中,uLong 和 z_size_t 是无符号 64 位类型;uInt 是无符号 32 位类型。 z_off_t 和 z_off64_t 是有符号 64 位类型。输入校验和值中高于第 31 位的位被忽略; 返回校验和值可用 32 位表示。显式 *64 声明取决于头文件的大文件特性宏。

adler32_z

uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len);

用一段字节更新 Adler-32,或取得初始值。

定义域。 受限定义域。当 buf 非 NULL 时,效果为只读。

前置条件: buf 为 NULL 且 len == 0,或它指向 len 个可读字节。 要满足校验和后置条件,adler 的低 32 位须为 A 的 Adler-32。 不要求任何准备或清理操作。

后置条件: NULL、零长度查询对任意 adler 都返回 1,不读取字节。 否则返回 A 后接 buf[0..len-1] 的 Adler-32。 非 NULL、零长度范围返回传入校验和值的低 32 位。

效果: 保持全部内存与所有权。只读取给定范围。 零长度范围允许使用尾后指针。

NULL 配合非零长度不在本契约范围内。伪造种子不属于本实用功能契约:单字节路径 不一定等价于先将种子的两个半部对 65521 取模。见 Adler 种子说明。

adler32

uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len);

用 32 位字节计数更新 Adler-32。

定义域。 受限定义域。当 buf 非 NULL 时,效果为只读。

前置条件: buf 为 NULL 且 len == 0,或它指向 len 个可读字节。 要满足校验和后置条件,adler 的低 32 位须为 A 的 Adler-32。

后置条件: 返回值与 adler32_z(adler, buf, len) 完全相同。 NULL、零长度查询返回 1。非 NULL 的空范围保持校验和值的低 32 位。

效果: 保持全部内存与所有权。只读取给定范围。 零长度范围允许使用尾后指针。

长度最多为 2^32 - 1。把更大长度转换为 uInt 会在调用前丢弃高位; 更大范围应使用 adler32_z 或分多次调用。 adler32_z 关于零长度 NULL 查询和伪造种子的范围同样适用。

adler32_combine

uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2);

计算 A 后接 B 的 Adler-32,而不读取任一序列。

定义域。 受限定义域。效果为纯计算。

前置条件: 要得到拼接结果,adler1 和 adler2 的低 32 位须分别为 A 和 B 的 Adler-32,且 len2 是 B 的长度。特别地,B 的校验和独立于 A,从 1 开始。 负长度仅纳入下述拒绝结果的范围。

后置条件: 若 len2 < 0,返回 0xFFFFFFFF。否则返回 A 后接 B 的 Adler-32。 空 B 的校验和为 1,合并后 A 的校验和不变。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。

该哨兵值不是有效的 Adler-32。任意标量参数不会导致内存访问;其精确的非校验和结果 由更宽的 Lean 契约描述。若 B 的长度错误,不保证拼接结果。

adler32_combine64

uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2);

使用显式 64 位长度计算 A 后接 B 的 Adler-32。

定义域。 受限定义域。效果为纯计算。

前置条件: 要得到拼接结果,adler1 和 adler2 的低 32 位须分别为独立计算的 A 和 B 的 Adler-32,且 len2 是 B 的长度。负长度纳入拒绝情形。

后置条件: 负长度返回 0xFFFFFFFF。否则返回 A 后接 B 的 Adler-32。 空 B 保持 A 的校验和不变。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。

在 LP64 下,它与 adler32_combine 的契约和长度范围相同。 显式位宽在其他构建中有意义;本页不涵盖那些构建。

get_crc_table

const z_crc_t FAR * ZEXPORT get_crc_table(void);

返回库逐字节计算 CRC 使用的表。

定义域。 完整类型定义域;没有参数。效果为纯计算,返回指向库内存的指针, 不读取表项。

前置条件: 库的固定 CRC 表存在,如所选构建中所示。 不要求准备调用。

后置条件: 返回非 NULL 指针,指向由 256 个 z_crc_t 表项组成的只读数组。 表项 i 表示从零寄存器出发处理字节 i 的反射 CRC 寄存器更新, 不包含公开校验和接口的取反步骤。重复调用返回相同指针。

效果: 保持全部内存与所有权。表仍由库持有,生存期覆盖整个程序。 调用者可读取这 256 项,但不得通过指针写入,也不得释放它。

zlib.h 将此入口列于文档化 API 之外的函数中。它只公开字节表,不公开相邻表或 交织表。此处 z_crc_t 为无符号 32 位类型。动态建表不属于本构建范围。

crc32_z

uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len);

用一段字节更新 CRC-32,或取得初始值。

定义域。 受限定义域。当 buf 非 NULL 时为只读,并读取库的固定 CRC 表。

前置条件: buf 为 NULL,或指向任意对齐的 len 个可读字节。 要满足校验和后置条件,crc 的低 32 位须为 A 的 CRC-32。 所选构建的固定 CRC 表存在。

后置条件: NULL buf 对任意 crc 和 len 都返回 0,不读取缓冲区。 否则返回 A 后接 buf[0..len-1] 的 CRC-32。 非 NULL 的空范围返回 crc 的低 32 位。

效果: 保持全部内存与所有权。只读取给定字节范围和库的固定表。 空范围允许使用尾后指针。

新校验和从 0 开始。函数内部完成 CRC 的取反步骤;调用者不得对运行值取反。 对齐方式不改变契约。字访问模型的限制记录在 安全模型和可信基中。

crc32

uLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len);

用 32 位字节计数更新 CRC-32。

定义域。 受限定义域。当 buf 非 NULL 时为只读,并读取库的固定表。

前置条件: buf 为 NULL,或指向任意对齐的 len 个可读字节。 要满足校验和后置条件,crc 的低 32 位须为 A 的 CRC-32。固定 CRC 表存在。

后置条件: 返回值与 crc32_z(crc, buf, len) 完全相同。 即使长度非零,NULL 也返回 0。非 NULL 的空范围保持传入校验和值的低 32 位。 取反在内部处理。

效果: 保持全部内存与所有权。只读取给定字节范围和库的固定表。 空范围允许使用尾后指针。

长度最多为 2^32 - 1。把更大计数转换为 uInt 会在调用前截断; 更大范围应使用 crc32_z 或分多次更新。

crc32_combine_gen64

uLong ZEXPORT crc32_combine_gen64(z_off64_t len2);

生成一个算子,供 B 长度相同的多次 CRC 合并复用。

定义域。 完整类型定义域。效果为纯计算,只读取库的固定表。

前置条件: 参数不受限制。所选构建的固定 CRC 表存在。 len2 可为任意有符号 64 位值。

后置条件: 负长度返回 0。非负长度返回非零 32 位算子,适用于 B 长度为 len2 的 crc32_combine_op。零长度返回 0x80000000。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。

算子只取决于长度。保持其值不变,即可用于 B 长度相同的任意 A 和 B。 它描述随长度推进校验和的运算,本身不是任何特定字节序列的校验和值。

crc32_combine_gen

uLong ZEXPORT crc32_combine_gen(z_off_t len2);

使用普通偏移类型生成 CRC 合并算子。

定义域。 完整类型定义域。效果为纯计算,只读取库的固定表。

前置条件: 参数不受限制。所选构建的固定 CRC 表存在。 len2 可为任意可表示的有符号值。

后置条件: 返回与 crc32_combine_gen64(len2) 相同的算子。 负长度返回 0;零返回 0x80000000;正长度返回适用于该 B 长度的非零 32 位算子。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。

LP64 下,普通长度和显式 64 位长度的范围相同。

crc32_combine_op

uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op);

使用预先生成的算子,计算 A 后接 B 的 CRC-32。

定义域。 受限定义域。效果为纯计算。

前置条件: 要得到拼接结果,crc1 和 crc2 的低 32 位须分别为 A 和 B 从 0 独立开始计算的 CRC-32。op 是按 B 的长度调用 crc32_combine_gen 或 crc32_combine_gen64 得到、且未经修改的结果。 独立的拒绝情形允许 op == 0 配合任意校验和参数。

后置条件: 返回 A 后接 B 的 CRC-32。若 op == 0,返回 0。 用于空 B 的算子保持 A 的校验和不变。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。 该算子可复用于 B 长度相同的任意序列对。

伪造算子或用于错误 B 长度的算子不受保证。 特别地,若 LP64 op 非零、但低 32 位全为零,调用可能不终止;这不在生成算子契约内。 零是拒绝值,不是无歧义的错误码,因为有效 CRC 也可能为零。

crc32_combine64

uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2);

计算 A 后接 B 的 CRC-32,而不读取任一序列。

定义域。 受限定义域。效果为纯计算,只读取库的固定表。

前置条件: 要得到拼接结果,crc1 和 crc2 的低 32 位须分别为独立计算的 A 和 B 的 CRC-32,且 len2 是 B 的长度。固定 CRC 表存在。 负长度纳入拒绝情形,对校验和不作限制。

后置条件: 负长度返回 0。否则返回 A 后接 B 的 CRC-32。 空 B 的 CRC 为 0,合并后 A 的校验和不变。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。 生成的算子满足 crc32_combine_op 的输入要求。

若校验和值任意且长度为零,实现返回低 32 位的异或。 错误长度不保证拼接结果。零也是可能的有效 CRC,因此负长度拒绝没有独立错误码。

crc32_combine

uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2);

使用普通偏移类型计算 A 后接 B 的 CRC-32。

定义域。 受限定义域。效果为纯计算,只读取库的固定表。

前置条件: 要得到拼接结果,crc1 和 crc2 的低 32 位须分别为 A 和 B 从 0 独立开始计算的 CRC-32,且 len2 是 B 的长度。固定 CRC 表存在。 负长度纳入拒绝情形,对校验和不作限制。

后置条件: 返回与 crc32_combine64(crc1, crc2, len2) 相同的结果。 负长度返回 0。真实的空 B 保持 A 的校验和不变。

效果: 保持全部内存与所有权。不读取缓冲区或流状态。

LP64 下,普通长度和显式 64 位长度的范围相同。 本页不包括动态建表、硬件 CRC 钩子或生成表的可执行程序。 见构建与模型范围。

返回 API 手册 · 契约约定

ZLIB × LEAN

全局目录

当前位置校验和