如何创建具有 22B 的最小大小(空)zip 文件?

How to create minimum size (empty) zip file, which has 22B?

我正在尝试解决文件的一些安全问题,其 MD5 哈希为 76cdb2bad9582d23c1f6f4d868218d6c。

我没有那个文件,但根据互联网 MD5 搜索,我认为它是最小尺寸的 zip 文件。 我找到了一个 example and its content is exactly same like minimum size zip file.

是否可以使用 Linux(或 Windows)命令创建这样的最小大小的 zip 文件(22 B)?

顺便说一句:最近,我用 gzip 文件解决了类似的任务:gzip -n EmptyFileName

给你:

50 4b 05 06 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00

具有您提供的 MD5 签名。

如果你有Info-ZIP的压缩包,可以这样创建:

zip empty.zip anyfile
zip -d empty.zip anyfile

将 "anyfile" 添加到新的 zip 文件,然后将其从 zip 文件中删除,使其为空。

一个更易于使用的版本,用于复制和粘贴到 shell:

echo UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA== | base64 -d > empty.zip

这只是打印空 zip 文件的 base64' 版本(通过创建一个带有单个文件的 zip 文件然后从 zip 文件中删除该单个文件创建),并使用 base64 -d 并将输出写入 empty.zip.


如果您的机器附带的 base64 版本不使用与上面相同的语法,这里有一个更便携但不太简洁的替代方法:

echo UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA==  | openssl enc -d -base64 > empty.zip

使用此 .bat 脚本,您可以在 windows 下创建 empty.zip 文件:

@echo off

del /q /f empty.zip >nul 2>nul
certutil -decode "%~f0" empty.zip

-----BEGIN CERTIFICATE-----
UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA==
-----END CERTIFICATE-----

tldr;

使用printf

$ printf '\x50\x4b\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' >empty.zip
$ md5sum empty.zip 
76cdb2bad9582d23c1f6f4d868218d6c  empty.zip

使用base64

$ base64 -d >empty.zip <<'EOF'
UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA==
EOF
$ md5sum empty.zip
76cdb2bad9582d23c1f6f4d868218d6c  empty.zip

说明

虽然 zip 工具不支持创建空的 zip 文件,但您可以创建一个 non-empty zip 文件,然后删除其内容:

$ touch foo.txt
$ zip empty.zip foo.txt
  adding: foo.txt (stored 0%)
$ zip -d empty.zip foo.txt
deleting: foo.txt
    zip warning: zip file empty

请注意 zipinfo returns 如何在给定结果 empty.zip:

时出错
$ zipinfo empty.zip 
Archive:  empty.zip
Zip file size: 22 bytes, number of entries: 0
Empty zipfile.
$ echo $?
1

您可以确认 empty.zip 具有预期的字节数:

$ file empty.zip
empty.zip: Zip archive data (empty)
$ xxd empty.zip
00000000: 504b 0506 0000 0000 0000 0000 0000 0000  PK..............
00000010: 0000 0000 0000                           ......

您可以使用 printf 将这 22 个字节(十六进制)直接写入文件:

$ printf '\x50\x4b\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' >empty.zip

您还可以将这 22 个字节转换为 32 个 base64 编码字符并使用:

$ base64 <empty.zip 
UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA==

使用 Info-Zip(标准 zip/unzip 安装在 Ubuntu 20.04 上),您必须使用 -i "*" 选项。如果它不存在,zip 将在创建时抱怨并以错误代码 1 退出。与直觉相反,它的行为随着 -i "*".

而改变
mkdir /tmp/mytest
cd /tmp/mytest
zip -r mytest.zip . -i "*"

mytest.zip 将是您想要的空 zip 文件。