打包容器和压缩器不是一回事
“压缩包”这个词底下混着两件不同的工作。打包是把许多文件放进一个文件,同时保留它们的文件名和文件夹结构。压缩是让字节变少。TAR只负责打包——一个.tar的大小就是里面所有文件大小的总和。Gzip只负责压缩,而且一次只能压缩一个数据流,这就是.tar.gz存在的原因:先打包,再压缩整个包。ZIP则两件事同时做,逐个文件压缩,并保留一份内容目录。
这个区别决定了格式在使用中的表现。ZIP把目录存在文件末尾,并且每个文件单独压缩,所以即使是10 GB的压缩包也能瞬间列出内容,还能从中间单独解压一个文件而不碰其余部分——我们的ZIP读取器正是这样做的:在您真正要某个文件之前,什么都不解压。固实压缩包则把所有内容当作一个连续的数据流来压缩,因此能发现跨文件的重复内容,结果更小;对于大量相似的小文件(例如源代码或日志),有时会小得多。代价是没有便捷的办法直接取出中间的某个文件:它之前的所有内容都必须先解压。TAR.GZ天生就是固实的,7z按固实块压缩,而RAR在这里是从头顺序读取的,而不是通过目录读取。
已经压缩过的内容不会再被压缩。JPEG、PNG、MP3、MP4、PDF以及所有现代Office文件都内置了压缩,deflate花时间处理它们却毫无收获——有时反而多出几个字节。这就是为什么一个照片文件夹打成ZIP后大小几乎不变,人们还以为是工具坏了。创建ZIP压缩包能识别这些格式,直接原样存储,而不是装模作样地压缩,所以处理照片时瞬间完成,处理文本时才会多花些时间。
压缩包携带的元数据并不等于您磁盘上的元数据。ZIP用MS-DOS格式存储修改时间,精度只有两秒,而且无法表示1980年之前或2099年之后的日期——超出范围的日期在这里会被限定到边界值,而不是让整个压缩包失败;这是我们在转换带有零日期的RAR时真实遇到过的bug。TAR会存储Unix权限、所有者和符号链接。浏览器既无法从您的磁盘读取这些信息,也无法把它们写回去,因此创建TAR压缩包会写入一个合理的默认权限,我们的解压工具也只会列出权限和链接,而不会还原它们。如果压缩包是一份必须原样恢复的备份,就应该在本机上用tar来创建和还原。
ZIP加密有两种,只有一种有用。最初的ZipCrypto方案已被攻破到形同虚设的地步——用已知明文攻击,普通硬件几秒钟就能恢复内容,而大多数软件至今仍默认提供它。后来加入的AES-256才是真正的加密,无法破解。这两种我们都不提供:破解过的那种我们不会上线,而现代的那种没有可在宽松许可证下使用的浏览器原生实现。无论如何都值得知道:ZIP从不加密文件名,所以加密压缩包的目录任何人都能看到。“Invoices/2024/Settlement-confidential.pdf”这样的文件名,不需要密码就能看见。
压缩包是唯一一种内容可能攻击打开它的程序的文件。里面的文件可以被命名为“../../.bashrc”,以逃出解压目标文件夹;几KB的数据也可以被精心构造成解压后达到数TB,把标签页拖垮。这两种情况在您看到任何内容之前就已处理好:恶意文件名——向上跳出父目录、绝对路径、Windows盘符、系统保留的设备名、用来伪装扩展名的不可见字符——都会被限定,每一处修正都会列出;解压膨胀比会被测量,超标的直接拒绝,而不是硬着头皮去解。压缩包内的符号链接会显示出来,但绝不会被跟随。
浏览器确实不适合的情况
这些工具的设计初衷就是让您的压缩包保持私密,而这是有代价的。我们宁可在这里说清楚,也不愿您做到一半才发现。
超大压缩包。所有内容都保存在您设备的内存里,所以上限取决于标签页的内存,而不是什么套餐限制。列出大型ZIP的内容成本很低,因为目录是单独读取的,但解压就不同了:几GB的压缩包在手机上会很吃力,在笔记本电脑上也可能失败。7-Zip、GNU tar和bsdtar直接从磁盘流式读取,文件再大也无所谓。
创建RAR或7z。这两者在这里都做不到,原因各不相同。RAR压缩是专有技术,唯一能创建RAR的代码的许可证禁止用它来开发其他压缩软件,所以任何浏览器工具都无法诚实地提供这项功能——ZIP转RAR页面正是为解释这一点而存在的。至于7z,读取可以借助一个独立编写的实现来完成,写入目前还没有这样的途径。如果您需要这两种格式,WinRAR可以创建前者,而7-Zip——免费,而且在这方面比任何网页都强——可以创建后者。
任何加密内容。我们无法创建带密码的压缩包,也无法打开它。要创建加密压缩包,免费的方案是使用AES-256的7-Zip,它相比任何网页还有一个额外优势:您的密码是输入到您自己安装的程序里,而不是互联网上的某个文本框里。
完整还原的备份。权限、所有者、符号链接和硬链接、扩展属性、稀疏文件以及精确的时间戳,正是备份要保存的东西,而浏览器一样都接触不到。GNU tar和bsdtar是免费的,macOS和Linux已经自带,它们才是合适的工具。
自动化和极限压缩。这些工具只在有人点击时才运行。每晚归档一个目录的任务应该交给命令行——tar、zip、7z和zstd都是免费的。如果您最在乎体积,deflate是一种上世纪90年代的算法:高压缩级别的zstd或xz压缩同样的文件,会比ZIP小得多,代价是收件人可能打不开这种格式。
名字相似的工具怎么选
ZIP解压、RAR解压、7Z解压与TAR解压。实际上,您打开哪一个都行。每个工具都是根据文件开头的几个字节而不是扩展名来识别文件的,所以四个工具都能打开全部格式,并告诉您这个文件实际上是什么格式——这一点很重要,因为为了绕过邮件过滤而把RAR改名为.zip的情况很常见。真正有差别的是格式而不是页面:ZIP可以通过目录瞬间列出内容,而RAR必须先完整读一遍,才能告诉您里面有什么。
创建ZIP压缩包与创建TAR压缩包。如果打开它的是人,就用ZIP——任何电脑无需安装软件都能打开。如果打开它的是机器或Linux用户,或者您有大量相似的小文件,就用TAR.GZ:把整个包当作一个数据流来压缩,结果明显比逐个文件压缩更小。不带任何压缩的纯TAR,只有在内容本身已经压缩过、或者后续环节会负责压缩时才值得选择。
RAR转ZIP与ZIP转RAR。一个是转换,另一个是说明。RAR转ZIP真的会读取您的RAR并写出一个ZIP,文件按字节原样复制,不会重新编码。ZIP转RAR则是一个说明页面,告诉您为什么没有人能做这种转换——否则这个搜索词就只能留给那些要么把您的文件拿到他们自己服务器上、要么给您一个改了名字的ZIP的网站。
创建ZIP压缩包与为节省空间而压缩。这不是同一个目标。把许多文件打成一个包方便发送,对任何文件都适用。想把一个大文件变小,通常却做不到,因为人们想缩小的大文件——视频、照片、PDF——本身都已经压缩过了。对于这些文件,本站的图片、视频和PDF压缩工具会重新编码内容,这才是真正能让它们变小的唯一方法。