我需要一个 10 MB 的 PDF 文件来测试上传限制。不是“大约 10 MB”,而是精确的 10,485,760 字节。我找到的每个生成器要么只能生成固定大小的文件,要么让我等待服务器下载。
因此,我研究如何在浏览器中实现这一功能。有趣的地方不在于文件大小,而在于在达到任意指定字节数的同时,保持文件有效。
naive(天真)的方法会破坏文件
显而易见的做法是:创建一个真实文件,然后附加垃圾字节直到达到目标大小。
const blob = new Blob([realPdf, padding]); // ← 已损坏
对于大多数格式而言,这会产生一个损坏的文件。PDF 阅读器会跟随交叉引用表找到字节偏移量;%%EOF 之后的尾部垃圾数据可能会使其出错。PNG 解码器会遍历带有长度前缀的数据块;末尾多余的字节不是一个有效的数据块。
诀窍在于,每种格式都已经为额外数据预留了合法的位置。你只需要将填充数据放在那里即可。
在规范允许的位置进行填充
-
PNG → 一个
tEXt元数据块。它具有长度前缀和 CRC-32 校验码,因此解码器会精确读取其声明的长度并跳过其余部分。完全有效。 - PDF → 一个未被引用的内容流。这与 PDF 写入器用于增量更新的机制相同——交叉引用表只是没有指向它。
- ZIP / DOCX / XLSX → 归档内部的一个存储(未压缩)条目。
-
JPEG →
COM注释段,每段最多 65,533 字节。
对于 PNG,填充块需要正确的 CRC 校验码,否则解码器会拒绝它:
function pngChunk(type, data) {
const body = concat(type, data);
const crc = crc32(body); // 必须正确
return concat(uint32(data.length), body, uint32(crc));
}
只要 CRC 校验码正确,文件就能在任何地方打开——填充数据是不可见的。
为什么浏览器端实现很重要
因为没有任何数据通过网络传输,文件大小几乎不影响速度。组装一个 100 MB 的文件是一个内存操作,而不是下载过程——它能在几十毫秒内完成。而且文件永远不会离开你的机器,因此没有上传、没有存储、也没有任何日志记录。
我使用真实的解析器验证了输出结果——pypdf 读取 PDF 文本,Pillow 解码 PNG,openpyxl 操
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。