summaryrefslogtreecommitdiff
path: root/_posts
diff options
context:
space:
mode:
Diffstat (limited to '_posts')
-rw-r--r--_posts/2026-10-01-quine.md562
1 files changed, 562 insertions, 0 deletions
diff --git a/_posts/2026-10-01-quine.md b/_posts/2026-10-01-quine.md
index 237eed8..bef3437 100644
--- a/_posts/2026-10-01-quine.md
+++ b/_posts/2026-10-01-quine.md
@@ -190,6 +190,568 @@ class BlogQuine:
于是我第一时间就把原来的TGZ压缩命令换掉,换成了AI给我写的[blogquine.py](https://github.com/Mabbs/mabbs.github.io/blob/master/_tools/blogquine.py),现在就可以通过[这里](https://mayx.eu.org/MayxBlog.7z)下载到“完整”包含我博客所有内容的压缩包了。
不过唯一的问题就是这样做出来的压缩包并没有压缩😂,相当于给做成了普通的归档了。当然我的博客本身倒是不大,没压缩也多不了多少空间,但相比于能做出“完整”的效果来说,这点浪费的空间也是小问题了。
+## 基于博客压缩包的离线模式(2026.10.03更新)
+ 既然现在的AI什么都能做了,那上次我因为技术不足仅仅只是用[Service Worker做了个代理](/2025/08/01/sw-proxy.html),现在也可以升级成下载全站之后让全站离线的功能吧?不过之前做的压缩包并没有压缩,导致整个压缩包有接近20MiB的大小,后来我仔细想了一下我的需求,我只是想让下载全站压缩包的按钮不断链,并没有说解压后的文件一定就必须是它本身,所以我只要用相同的文件名再压缩一次应该就可以了,这样既能满足我的想法,又可以让其他人下载的时候不会花费太多的时间。
+ 在我直接压缩之后,整个压缩包占用大概9MiB的空间,其实我已经很满意了,不过压之前是18MiB,也就是说压缩率是50%……虽然也不是不能接受,但我在想这是不是合理的结果呢?我让AI分析了一下50%的压缩率正不正常,它看了一眼之后告诉我文本部分的10MiB压缩完之后有1MiB,图片因为压不动所以直接占用了8MiB😅,这时候我才意识到原来我一直存着一堆占着大量空间的垃圾,而且还是用的PNG/JPG这种压缩率很低的格式……考虑到兼容性和压缩效果,我把占用比较大的图片转换为了WebP格式,最终整个压缩包就只占用了4MiB的空间,一口气又节省了50%的空间。
+ 最后做完对压缩包的处理之后,我直接让AI给我基于那个压缩包制作离线模式,它轻轻松松就[做出来](https://mayx.eu.org/offline.html)了,最终使用的是[libarchive库](https://github.com/nika-begiashvili/libarchivejs),在启用离线模式之后整个网站的速度简直就是0延迟,点击就能瞬间跳转,效果算是相当不错了。
+## 受大佬启发制作了能压缩的7z Quine(2026.10.05更新)
+ 做完博客压缩包之后我突发奇想,虽然东西是AI做的,但也是在我的手中做出了世界上第一个LZMA2 Quine,那么如果我向全世界第一个制作ZIP Quine的人展示一下我的作品会怎么样呢?目前可以知道,世界上第一个制作ZIP Quine的人是[Erling Ellingsen](https://infosec.exchange/@steike),所以我向他发了个帖子[展示了一下](https://infosec.exchange/@mayx/117385801954308033)。大佬不愧是大佬,一眼就能看出理论上能压缩的7z Quine是可以做出来的,对我来说,我是完全不知道7-Zip居然还支持链式编解码,能可以通过“double lzma2”的方式做到既可以自包含、又能真正被压缩的压缩包。既然大佬说理论上可以,那我自然是相信的,于是就让AI给我使劲折腾想办法把它做出来。在折腾了一晚上之后AI终于做出来了,真是强得可怕:
+```python
+# ============================================================
+# 双层 LZMA2 的 7z quine("double lzma2")
+#
+# F = S32 ‖ P ‖ H,folder 的 coder 链 = [LZMA2(外层), LZMA2(内层)],
+# 解码管线:P --外层--> I --内层--> U。
+#
+# I = Cseg ‖ LBseg ‖ Mseg ‖ 0x00
+# Cseg : 真实 LZMA2 对 content 的压缩流(内容真正的压缩数据 C)
+# LBseg: 内层 store 链,载荷 = seed(seed 内含一份 C 的参照副本)
+# Mseg : 内层 match 链,输出 quine 区(= F 的逐字节副本)
+# U = content ‖ seed ‖ F
+#
+# 外层把 I 再压一遍:Cseg 用 store 链原样承载;seed 里的 C 参照副本与 Cseg
+# 逐字节相同,被外层的 rep0 回溯匹配消掉,于是成品里只剩一份压缩数据。
+# quine 区回引 P 的字节时,源全在 seed 里(C 副本 / 头样本表 / 机械串)。
+# ============================================================
+def lzma_chunk(tokens, out_pos):
+ """编一个 LZMA chunk(0xC0: state+props reset,无 dict reset,无 end marker)。
+ match token 的编码字节只取决于 (dist,len,pos),与历史内容无关(不维护输出历史)。
+ 解压长度用 21 位(控制字节低 5 位存高 5 位),故单 chunk 输出上限 2 MiB。"""
+ enc = LzmaEncoder()
+ enc.pos = out_pos
+ total = 0
+ for t in tokens:
+ if t[0] == "m":
+ enc.match(t[1], t[2])
+ total += t[2]
+ else:
+ enc.rep_match(t[1])
+ total += t[1]
+ data = enc.finish()
+ u = total - 1
+ c = len(data) - 1
+ assert 0 <= u < (1 << 21) and 0 <= c < 65536, (total, len(data))
+ hdr = bytes([0xC0 | ((u >> 16) & 0x1F)]) + (u & 0xFFFF).to_bytes(2, "big") + \
+ (c & 0xFFFF).to_bytes(2, "big") + bytes([PROPS_BYTE])
+ return hdr + data, total
+
+LZ2_MAXU = 1 << 21 # LZMA2 单个 LZMA chunk 的解压上限
+
+
+def lzma2_raw(data, dict_size, preset=6):
+ """FORMAT_RAW + LZMA2 压缩;去掉结尾 0x00 便于后面继续追加 chunk。"""
+ c = lzma.LZMACompressor(
+ format=lzma.FORMAT_RAW,
+ filters=[{"id": lzma.FILTER_LZMA2, "dict_size": dict_size, "preset": preset}])
+ out = c.compress(data) + c.flush()
+ assert out and out[-1] == 0x00, "LZMA2 流应以 0x00 结尾"
+ return out[:-1]
+
+
+def split_len(n, cap):
+ """按 cap 上限切分 n 字节。末片若为 1 字节则从前一片借 1(match 最短为 2)。"""
+ Ls, rem = [], n
+ while rem > cap:
+ Ls.append(cap)
+ rem -= cap
+ if rem == 1 and Ls:
+ Ls[-1] -= 1
+ rem = 2
+ Ls.append(rem)
+ return Ls
+
+
+class DoubleQuine(BlogQuine):
+ """双层 LZMA2 版本:folder = [LZMA2(外层), LZMA2(内层)]。"""
+
+ def entries(self):
+ """U 的顺序是 内容文件… ‖ seed ‖ quine,条目顺序必须与之对应。"""
+ ent = [{"name": r, "dir": isd} for r, isd in self.walk_entries]
+ ent.append({"name": self.seed_name, "dir": False})
+ ent.append({"name": self.quine_name, "dir": False})
+ return ent
+
+ # ---------- 头部:双 coder + BindPair ----------
+ def build_header(self, n, total, d, entries, sub_sizes, size_I):
+ n_sub = len(sub_sizes)
+ N = len(entries)
+ h = bytearray()
+ h += b"\x01\x04" # kHeader, kMainStreamsInfo
+ h += b"\x06" + varint(0) + varint(1) + b"\x09" + varint(n) + b"\x00"
+ h += b"\x07" # kUnpackInfo
+ h += b"\x0b" + varint(1) + b"\x00" # kFolder: 1, local
+ h += varint(2) # NumCoders = 2
+ h += b"\x21\x21" + varint(1) + bytes([self.dict_prop_out]) # coder0 = 外层
+ h += b"\x21\x21" + varint(1) + bytes([self.dict_prop_in]) # coder1 = 内层
+ h += varint(1) + varint(0) # BindPair = (InIndex=1, OutIndex=0)
+ h += b"\x0c" + varint(size_I) + varint(d + total) # 两个 coder 的输出大小
+ h += b"\x00"
+ h += b"\x08" # SubStreamsInfo
+ h += b"\x0d" + varint(n_sub)
+ h += b"\x09" + b"".join(varint(s) for s in sub_sizes[:-1])
+ h += b"\x0a" + b"\x01"
+ crc_base = len(h)
+ h += b"\x00" * (4 * n_sub)
+ h += b"\x00\x00"
+ h += b"\x05" + varint(N) # FilesInfo
+ bits = bytearray((N + 7) // 8)
+ for i, e in enumerate(entries):
+ if e["dir"]:
+ bits[i // 8] |= 1 << (7 - i % 8)
+ h += b"\x0e" + varint(len(bits)) + bytes(bits)
+ mt = b"\x01\x00" + struct.pack("<Q", self.mtime_ft) * N
+ h += b"\x14" + varint(len(mt)) + mt
+ names = bytearray(b"\x00")
+ for e in entries:
+ names += e["name"].encode("utf-16-le") + b"\x00\x00"
+ h += b"\x11" + varint(len(names)) + bytes(names)
+ attrs = b"".join(struct.pack("<I", 0x10 if e["dir"] else 0x20)
+ for e in entries)
+ h += b"\x15" + varint(2 + len(attrs)) + b"\x01\x00" + attrs
+ h += b"\x00\x00"
+ return bytes(h), crc_base
+
+ # ---------- 布局:三层坐标的不动点迭代 ----------
+ def layout(self):
+ content = self.content
+ dc = len(content)
+ dict_c = max(1 << 20, 1 << max(20, dc.bit_length()))
+ C = lzma2_raw(content, dict_c)
+ self._C = C # 内容压缩只做一次,finalize 复用
+ lc = len(C)
+ # 迭代变量:Y = plant 长度, H = 头部长度, M = Mseg 字节数
+ Y, H, M = 96, 256, 256
+ seen = set()
+ for _ in range(200):
+ ds = lc + 32 + H + Y # seed = C副本‖S32‖H‖plant
+ d = dc + ds
+ Ls_LB = split_len(ds, CHUNK)
+ lLB = 3 * len(Ls_LB) + ds
+ off_in = lc + lLB
+ M1 = M + 1 # Mseg ‖ 内层流终止符 0x00
+ Ls_M = split_len(M1, CHUNK)
+ Li = off_in + M1
+ self.dict_prop_out, _ = dict_prop_for(max(Li, 1 << 20))
+ self.dict_prop_in, _ = dict_prop_for(d + 32 + H + 8192)
+ st = self._build_streams(C, lc, ds, d, Ls_LB, lLB, off_in, Ls_M,
+ M1, H)
+ if st is None:
+ Y += 8
+ continue
+ mseg = self._build_mseg(st, d, lc, ds, H, M)
+ if mseg is None:
+ Y += 8
+ continue
+ M_new = len(mseg)
+ Y_new = len(st["hdr_bytes"]) + len(st["mech"]) + M_new + 2
+ total = st["n"] + 32 + H
+ file_sizes = [len(x) for _, x in self.files]
+ sub_sizes = file_sizes + [ds] + [total]
+ entries = self.entries()
+ hdr, crc_base = self.build_header(st["n"], total, d, entries,
+ sub_sizes, Li)
+ H_new = len(hdr)
+ key = (Y_new, H_new, M_new)
+ if key in seen: # 再次见到同一组值 = 已收敛
+ Y, H, M = Y_new, H_new, M_new
+ break
+ seen.add(key)
+ Y, H, M = Y_new, H_new, M_new
+ else:
+ raise RuntimeError("double layout 不收敛")
+ return {"Y": Y, "H": H, "M": M}
+
+ # ---------- 定稿:用收敛后的 (Y, H, M) 重算全部结构 ----------
+ def finalize(self, Y, H, M):
+ content = self.content
+ dc = len(content)
+ C = self._C # layout 里已压缩过
+ lc = len(C)
+ ds = lc + 32 + H + Y
+ d = dc + ds
+ Ls_LB = split_len(ds, CHUNK)
+ lLB = 3 * len(Ls_LB) + ds
+ off_in = lc + lLB
+ M1 = M + 1
+ Ls_M = split_len(M1, CHUNK)
+ Li = off_in + M1
+ self.dict_prop_out, ds_out = dict_prop_for(max(Li, 1 << 20))
+ self.dict_prop_in, ds_in = dict_prop_for(d + 32 + H + 8192)
+ st = self._build_streams(C, lc, ds, d, Ls_LB, lLB, off_in, Ls_M, M1, H)
+ mseg = self._build_mseg(st, d, lc, ds, H, M)
+ assert len(mseg) == M, "Mseg %d != %d" % (len(mseg), M)
+ total = st["n"] + 32 + H
+ file_sizes = [len(x) for _, x in self.files]
+ sub_sizes = file_sizes + [ds] + [total]
+ entries = self.entries()
+ hdr, crc_base = self.build_header(st["n"], total, d, entries,
+ sub_sizes, Li)
+ assert len(hdr) == H, "header %d != %d" % (len(hdr), H)
+ plant = st["hdr_bytes"] + bytes(st["mech"]) + mseg + b"\x00\x00"
+ assert len(plant) == Y, "plant %d != %d" % (len(plant), Y)
+ return {"C": C, "lc": lc, "dc": dc, "ds": ds, "d": d, "Li": Li,
+ "ochunks": st["ochunks"], "hdr_tab": st["hdr_tab"],
+ "mseg": mseg, "M": M, "H": H, "n": st["n"], "total": total,
+ "header": hdr, "crc_base": crc_base, "plant": plant,
+ "dict_size_in": ds_in, "dict_size_out": ds_out,
+ "n_sub": len(sub_sizes)}
+
+ # ---------- 外层流 P 的构造 ----------
+ def _build_streams(self, C, lc, ds, d, Ls_LB, lLB, off_in, Ls_M, M1, H):
+ hdr_tab, hdr_idx = [], {}
+
+ def hidx(b):
+ assert len(b) == 3 and b[0] in (0x01, 0x02), b.hex()
+ if b not in hdr_idx:
+ hdr_idx[b] = len(hdr_tab)
+ hdr_tab.append(b)
+ return hdr_idx[b]
+
+ ochunks = []
+ f, io = 32, 0
+ mech = bytearray()
+
+ def put_lzma(tokens, ioff):
+ blk, t = lzma_chunk(tokens, ioff)
+ ochunks.append({"kind": "lzma", "foff": f, "size": len(blk),
+ "ioff": ioff, "olen": t, "bytes": blk,
+ "mech": len(mech)})
+ mech.extend(blk)
+ return len(blk), t
+
+ def put_store(ioff, olen, hi, src):
+ ochunks.append({"kind": "store", "foff": f, "size": 3 + olen,
+ "ioff": ioff, "olen": olen, "hdr": hi, "src": src})
+ return 3 + olen
+
+ # 段 1:store 链承载 Cseg(I[0:lc] = C 的字节;源 = seed 的 C 参照副本)
+ Ls_C = split_len(lc, CHUNK)
+ c_off = 0
+ for L in Ls_C:
+ f += put_store(io, L, hidx(store_hdr(L, first=(c_off == 0))),
+ ("seed", c_off))
+ io += L
+ c_off += L
+ assert io == lc
+
+ # 段 2:LBseg(I[lc : lc+lLB])—— 内层 store 链,载荷 = seed
+ lb_off = lc
+ seed_off = 0
+ for j, L in enumerate(Ls_LB):
+ lb_hdr = store_hdr(L, first=False)
+ if j == 0 or L != CHUNK:
+ # 没有可回引的相同样本,用外层 store chunk 原样携带这 3 字节
+ f += put_store(lb_off, 3, hidx(store_hdr(3, first=False)),
+ ("tab", hidx(lb_hdr)))
+ io += 3
+ else:
+ # 与 chunk0 的头逐字节相同,直接从 I[lc:lc+3] 复制
+ n, t = put_lzma([("m", lb_off - lc, 3)], lb_off)
+ assert t == 3
+ f += n
+ io += 3
+ # 载荷:C 参照副本区走 rep0 回溯匹配(去重发生处),其余走 store
+ pay = lb_off + 3
+ i = 0
+ while i < L:
+ if seed_off + i < lc:
+ a = min(L - i, lc - (seed_off + i), LZ2_MAXU)
+ dist = (pay + i) - (seed_off + i)
+ n, t = put_lzma(matches_for(dist, a), pay + i)
+ assert t == a
+ f += n
+ io += a
+ i += a
+ else:
+ a = min(L - i, LZ2_MAXU)
+ f += put_store(pay + i, a, hidx(store_hdr(a, first=False)),
+ ("seed", seed_off + i))
+ io += a
+ i += a
+ lb_off += 3 + L
+ seed_off += L
+ assert lb_off == lc + lLB and io == lc + lLB
+
+ # 段 3:store 链承载 Mseg ‖ 0x00(0x00 是内层流的终止符)
+ m_off = 0
+ for L in Ls_M:
+ f += put_store(off_in + m_off, L,
+ hidx(store_hdr(L, first=False)), ("mseg", m_off))
+ io += L
+ m_off += L
+ # 外层流自己的终止符 0x00
+ ochunks.append({"kind": "term", "foff": f, "size": 1, "ioff": io,
+ "olen": 0, "bytes": b"\x00"})
+ f += 1
+ return {"ochunks": ochunks, "mech": mech, "hdr_tab": hdr_tab,
+ "hdr_bytes": b"".join(hdr_tab), "n": f - 32}
+
+ # ---------- 内层 Mseg:把 quine 区的每个 F 区段映射成 match 链 ----------
+ def _build_mseg(self, st, d, lc, ds, H, M):
+ dc = d - ds
+ s_S32 = dc + lc # seed 里 S32 副本
+ s_H = dc + lc + 32 # seed 里 H 副本
+ s_tab = dc + lc + 32 + H # seed 里头样本表
+ s_mech = s_tab + len(st["hdr_bytes"]) # seed 里机械串
+ s_mseg = s_mech + len(st["mech"]) # seed 里 Mseg 副本
+ total = st["n"] + 32 + H
+ hoff = 32 + st["n"]
+ segs = [(0, 32, s_S32)] # F[0:32) 签名头
+ for c in st["ochunks"]:
+ if c["kind"] == "store":
+ segs.append((c["foff"], 3, s_tab + 3 * c["hdr"]))
+ src = c["src"]
+ if src[0] == "seed":
+ u = dc + src[1]
+ elif src[0] == "tab":
+ u = s_tab + 3 * src[1]
+ else: # ("mseg", off)
+ u = s_mseg + src[1]
+ segs.append((c["foff"] + 3, c["olen"], u))
+ elif c["kind"] == "lzma":
+ segs.append((c["foff"], c["size"], s_mech + c["mech"]))
+ else: # term:并入前一个载荷段
+ pf, pl, pu = segs[-1]
+ segs[-1] = (pf, pl + 1, pu)
+ segs.append((hoff, H, s_H)) # F[hoff:] 头部
+ pos = 0
+ for (fo, ln, u) in segs:
+ assert fo == pos, "段不连续: %d != %d" % (fo, pos)
+ assert ln >= 2, "段太短 %d @%d" % (ln, fo)
+ pos += ln
+ assert pos == total, "段总长 %d != total %d" % (pos, total)
+ # 生成 match 链,按 2 MiB 上限切成多个 0xC0 chunk
+ mseg = bytearray()
+ out_pos = d
+ cur, cur_len = [], 0
+ chunks = []
+ for (fo, ln, u) in segs:
+ dist = (d + fo) - u
+ assert 0 < dist, "dist=%d @%d" % (dist, fo)
+ toks = matches_for(dist, ln)
+ if cur_len + ln > LZ2_MAXU - MAX_MATCH:
+ chunks.append((cur, out_pos, cur_len))
+ out_pos += cur_len
+ cur, cur_len = [], 0
+ cur.extend(toks)
+ cur_len += ln
+ if cur:
+ chunks.append((cur, out_pos, cur_len))
+ out_pos += cur_len
+ assert out_pos == d + total, "Mseg 输出 %d != %d" % (out_pos, d + total)
+ for (toks, op, cl) in chunks:
+ blk, t = lzma_chunk(toks, op)
+ assert t == cl
+ mseg.extend(blk)
+ return bytes(mseg)
+
+ # ---------- F 中承载 seed[soff] 的那个字节的偏移 ----------
+ def _f_off_of_seed(self, lay, soff):
+ """返回 (F 偏移, 该 store 载荷内从 soff 起还剩多少字节)。
+ seed_head 超过 64 KiB 时会被切成多片,所以调用方要循环推进。"""
+ for c in lay["ochunks"]:
+ if c["kind"] == "store" and c["src"][0] == "seed":
+ s0 = c["src"][1]
+ if s0 <= soff < s0 + c["olen"]:
+ return c["foff"] + 3 + (soff - s0), s0 + c["olen"] - soff
+ raise RuntimeError("seed 偏移 %d 未被 store 载荷覆盖" % soff)
+
+ def _f_pos_list(self, lay, soff, length):
+ """seed[soff:soff+length] 在 F 中对应的字节位置列表(可能跨多片)。"""
+ res = []
+ while length > 0:
+ p, avail = self._f_off_of_seed(lay, soff)
+ a = min(length, avail)
+ res.extend(range(p, p + a))
+ soff += a
+ length -= a
+ return res
+
+ # ---------- 装配 ----------
+ def assemble(self, lay):
+ total, H = lay["total"], lay["H"]
+ hoff = total - H
+ C, plant = lay["C"], lay["plant"]
+ F = bytearray(total)
+ # pass A: 签名头 + 所有非 store 载荷字节
+ F[0:6] = SIG
+ F[6:8] = VER
+ struct.pack_into("<Q", F, 12, lay["n"])
+ struct.pack_into("<Q", F, 20, H)
+ for c in lay["ochunks"]:
+ if c["kind"] == "store":
+ F[c["foff"]:c["foff"] + 3] = lay["hdr_tab"][c["hdr"]]
+ else:
+ F[c["foff"]:c["foff"] + c["size"]] = c["bytes"]
+ F[hoff:hoff + H] = lay["header"]
+ # pass B: seed = C副本 ‖ S32副本 ‖ H副本 ‖ plant
+ seed = bytearray()
+ seed += C
+ seed += bytes(F[0:32])
+ seed += bytes(F[hoff:hoff + H])
+ seed += plant
+ assert len(seed) == lay["ds"], "seed %d != %d" % (len(seed), lay["ds"])
+ # pass C: 各 store 的载荷
+ msegz = lay["mseg"] + b"\x00"
+ for c in lay["ochunks"]:
+ if c["kind"] != "store":
+ continue
+ p = c["foff"] + 3
+ src, L = c["src"], c["olen"]
+ if src[0] == "seed":
+ F[p:p + L] = seed[src[1]:src[1] + L]
+ elif src[0] == "tab":
+ F[p:p + 3] = lay["hdr_tab"][src[1]]
+ else:
+ F[p:p + L] = msegz[src[1]:src[1] + L]
+ return F, bytes(seed)
+
+ # ---------- CRC 定点(128x128 GF(2):seed/quine/Next/Start 四个 CRC) ----------
+ def solve_crc(self, F, lay, C, plant):
+ H, hoff = lay["H"], lay["total"] - lay["H"]
+ n_sub, crc_base = lay["n_sub"], lay["crc_base"]
+ lc = lay["lc"]
+ # seed 里 S32 / H 副本在 F 中的镜像(可能跨多片,逐字节列出)
+ scopy0 = self._f_pos_list(lay, lc, 32)
+ Fv = memoryview(F)
+
+ def seed_crc():
+ v = crc32(C)
+ v = crc32(Fv[0:32], v) # S32 副本
+ v = crc32(Fv[hoff:hoff + H], v) # H 副本
+ return crc32(plant, v)
+
+ def targets():
+ return (seed_crc(), crc32(Fv), crc32(Fv[hoff:hoff + H]),
+ crc32(Fv[12:32]))
+
+ # 已知:各内容文件的 CRC,写本体 + seed 里 H 副本的镜像两处
+ known = [crc32(data) for _, data in self.files]
+ for i, e in enumerate(known):
+ slot = crc_base + 4 * i
+ b = struct.pack("<I", e)
+ for k in range(4):
+ F[hoff + slot + k] = b[k]
+ mir = self._f_pos_list(lay, lc + 32 + slot, 4)
+ assert len(mir) == 4
+ for k in range(4):
+ F[mir[k]] = b[k]
+ # 未知量:D_seed(seed 的 CRC)、D(quine 的 CRC)、N、S
+ # 每个未知量 4 字节,每字节有"本体 + seed 镜像"两个落点
+ qs = crc_base + 4 * len(known) # seed 子流的 CRC 槽
+ q = crc_base + 4 * (n_sub - 1) # quine 子流的 CRC 槽
+ groups = []
+ for slot in (qs, q):
+ groups.append([list(range(hoff + slot, hoff + slot + 4)),
+ self._f_pos_list(lay, lc + 32 + slot, 4)])
+ groups.append([list(range(28, 32)), scopy0[28:32]]) # NextHeaderCRC
+ groups.append([list(range(8, 12)), scopy0[8:12]]) # StartHeaderCRC
+ nb = 32 * len(groups)
+ base = targets()
+ basevec = 0
+ for i, v in enumerate(base):
+ basevec |= v << (32 * i)
+ cols = []
+ for g in range(len(groups)):
+ own, mir = groups[g]
+ for kb in range(32):
+ bi, bb = kb // 8, kb % 8
+ poss = [own[bi], mir[bi]]
+ for p in poss:
+ F[p] ^= (1 << bb)
+ t = targets()
+ for p in poss:
+ F[p] ^= (1 << bb)
+ delta = 0
+ for i, v in enumerate(t):
+ delta |= (v ^ base[i]) << (32 * i)
+ cols.append(delta)
+ eqs = []
+ for i in range(nb):
+ coeff = 0
+ for j in range(nb):
+ if (cols[j] >> i) & 1:
+ coeff |= 1 << j
+ coeff ^= 1 << i
+ eqs.append([coeff, (basevec >> i) & 1])
+ for j in range(nb):
+ p = next((i for i in range(j, nb) if (eqs[i][0] >> j) & 1), None)
+ if p is None:
+ raise RuntimeError("GF(2) 奇异 @bit%d" % j)
+ eqs[j], eqs[p] = eqs[p], eqs[j]
+ for i in range(nb):
+ if i != j and ((eqs[i][0] >> j) & 1):
+ eqs[i][0] ^= eqs[j][0]
+ eqs[i][1] ^= eqs[j][1]
+ x = 0
+ for i in range(nb):
+ assert eqs[i][0] == (1 << i)
+ if eqs[i][1]:
+ x |= 1 << i
+ vals = [(x >> (32 * i)) & 0xFFFFFFFF for i in range(len(groups))]
+ for g in range(len(groups)):
+ own, mir = groups[g]
+ b = struct.pack("<I", vals[g])
+ for k in range(4):
+ F[own[k]] = b[k]
+ F[mir[k]] = b[k]
+ t = targets()
+ assert t == tuple(vals), "CRC 定点失败: %s != %s" % (t, vals)
+ return vals
+
+ def build(self):
+ l0 = self.layout()
+ lay = self.finalize(l0["Y"], l0["H"], l0["M"])
+ F, seed = self.assemble(lay)
+ crcs = self.solve_crc(F, lay, lay["C"], lay["plant"])
+ # CRC 定点会改写 H / S32,而 seed 是它们的镜像,定点后需重建
+ hoff = lay["total"] - lay["H"]
+ seed = lay["C"] + bytes(F[0:32]) + bytes(F[hoff:hoff + lay["H"]]) \
+ + lay["plant"]
+ return bytes(F), lay, seed, crcs
+
+
+def verify_double(F, lay, files, seed, content):
+ """串联两个原始 LZMA2 解码器还原 U,逐段校验。"""
+ d, total = lay["d"], lay["total"]
+ dec_o = lzma.LZMADecompressor(
+ format=lzma.FORMAT_RAW,
+ filters=[{"id": lzma.FILTER_LZMA2, "dict_size": lay["dict_size_out"]}])
+ I = dec_o.decompress(F[32:32 + lay["n"]])
+ ok = True
+ if len(I) != lay["Li"]:
+ print("[verify] 外层输出 %d != I %d" % (len(I), lay["Li"]))
+ return False
+ dec_i = lzma.LZMADecompressor(
+ format=lzma.FORMAT_RAW,
+ filters=[{"id": lzma.FILTER_LZMA2, "dict_size": lay["dict_size_in"]}])
+ U = dec_i.decompress(I)
+ exp = d + total
+ if len(U) != exp:
+ print("[verify] 内层输出 %d != %d" % (len(U), exp))
+ return False
+ dc, ds = lay["dc"], lay["ds"]
+ if U[:dc] != content:
+ print("[verify] 内容不匹配")
+ ok = False
+ pos = 0
+ for rel, data in files: # 内容文件排在 U 的最前面
+ if U[pos:pos + len(data)] != data:
+ print("[verify] 文件不匹配:", rel)
+ ok = False
+ pos += len(data)
+ assert pos == dc
+ if U[dc:dc + ds] != seed:
+ print("[verify] seed 不匹配")
+ ok = False
+ if U[d:] != F:
+ print("[verify] quine 自复制不匹配")
+ ok = False
+ print("[verify] 自解码: |I|=%d, |U|=%d, seed/文件/quine 全部匹配: %s"
+ % (len(I), len(U), ok))
+ return ok
+```
+ 仅仅是大佬的一句话,AI就能做出来,实在是太可怕了。最终我试了一下,官方的7-Zip可以正常解压,但是Windows资源管理器不行……Windows资源管理器使用的也是[libarchive](https://github.com/libarchive/libarchive),似乎是因为libarchive只支持2个解码器,并且[第二个解码器只能是像BCJ这样的过滤器](https://github.com/libarchive/libarchive/blob/8bb3bbdc7b117a1e22086a2260f2087aafa90687/libarchive/archive_read_support_format_7zip.c#L1475)……明明7-Zip官方是可以解压的,不知道如果把这个问题当作BUG报告给libarchive他们会不会解决?但目前存在兼容性问题的话我博客压缩包就先不用这个方案了吧🥲……
## 对TXZ格式的尝试
在做完7z格式的压缩包之后,我发现了一个问题,虽然7z确实很流行,但是在Linux下解压起来有点麻烦,7-Zip历史上主要面向Windows,Linux上长期以来更多依赖p7zip等第三方移植,因此生态集成度不如tar.xz,想要解压7z文件还得额外安装。
不过Linux下也有个支持LZMA2算法的压缩软件,那就是前些年出过[后门](https://tukaani.org/xz-backdoor/)的XZ Utils,配合tar就可以做出TXZ(tar.xz)文件,甚至用我[博客终端](https://mabbs.github.io/linux/)中的BusyBox也能解压。我想了一下反正有AI,干脆一句话让AI帮我把blogquine.py改成tar.xz格式的好了,结果倒也没费多少功夫,AI就这样写出来了: