test(zlib-dbg): 加字面量码表探针(直方图/no_code/sum15 完整码校验),定位 comp 远小于熵下限的根因层

This commit is contained in:
TermiNexus committed 2026-10-03 13:15:06 +08:00
1 parent 3466b61c58
commit 6083d17826
1 file changed
+54
+54
View File
@@ -3,6 +3,7 @@ import zlib.pyzlib as pyzlib
import zlib.zdeflate as zdeflate
import zlib.zinflate as zinflate
import zlib.zdef as zdef
import zlib.zhuff as zhuff
import string
import stdlib
import testcheck
@@ -18,6 +19,53 @@ def fill_data(data: BYTEPTR, size: t.CSizeT, seed: t.CSizeT, repeating: t.CInt):
data[i] = BYTE((i * 31 + seed * 17 + (i * i) % 251) % 256)
def huffman_probe(seed: t.CSizeT, size: t.CSizeT, repeating: t.CInt):
"""对 roundtrip 的同一份数据直接用 zhuff 复算字面量码表并打印分布。
背景:随机数据的 comp 远小于其字面量熵下限(250 字节数据熵下限约 221 字节,
实测 comp=132),说明码表/码长分配异常。本探针打印:
- active:拿到码位(bits>0)的符号数
- no_code:有频率却拿不到码位的符号数(编码期会被 encode_symbol 静默丢弃)
- sum15:Σ hist[b]*2^(15-b),合法完整码表必须恰为 32768(=2^15)
再逐位宽打印码字数直方图。
"""
data: BYTEPTR = BYTEPTR(stdlib.malloc(size))
fill_data(data, size, seed, repeating)
freqs: t.CArray[t.CInt, 288]
string.memset(freqs, 0, freqs.__sizeof__())
i: t.CSizeT
for i in range(size):
freqs[data[i]] += 1
freqs[256] = 1
tree = zhuff.zhuff_tree()
tree.build_codes(freqs, 257, 15)
hist: t.CArray[t.CInt, 16]
string.memset(hist, 0, hist.__sizeof__())
active: t.CInt = 0
no_code: t.CInt = 0
sum15: t.CInt = 0
k: t.CInt
bits: t.CInt
for k in range(257):
bits = tree.codes[k].bits
if freqs[k] > 0 and bits == 0:
no_code += 1
if bits > 0 and bits < 16:
active += 1
hist[bits] += 1
sum15 += 1 << (15 - bits)
testcheck.info(f"[probe seed={seed} size={size} rep={repeating}] "
f"active={active} no_code={no_code} sum15={sum15} (期望 32768)")
for k in range(1, 16):
if hist[k] > 0:
testcheck.info(f" bits={k} codes={hist[k]}")
stdlib.free(data)
def roundtrip(seed: t.CSizeT, size: t.CSizeT, repeating: t.CInt, wbits: t.CInt) -> t.CInt:
data: BYTEPTR = BYTEPTR(stdlib.malloc(size))
fill_data(data, size, seed, repeating)
@@ -56,6 +104,12 @@ def roundtrip(seed: t.CSizeT, size: t.CSizeT, repeating: t.CInt, wbits: t.CInt)
def main() -> t.CInt:
testcheck.begin("ZlibDbg: zlib 多 seed/size/wbits 往返")
# 先跑码表探针:定位 comp 远小于熵下限的根因(码表异常 / 还是别处)
testcheck.section("字面量码表探针")
huffman_probe(0, 250, 0)
huffman_probe(9, 20000, 0)
huffman_probe(0, 256, 1)
testcheck.section("随机数据 (wbits=15)")
sizes: t.CArray[t.CSizeT, None] = [250, 255, 256, 257, 260, 300, 500, 1000, 4096, 20000]
n: t.CInt