製作 ZIP 壓縮檔
這件事本來就不需要伺服器。
本機處理把檔案拖進來,或點擊選擇
任何檔案類型、任何數量都可以。沒有大小上限,不用註冊。
「自動判斷」會把已經壓縮過的格式(JPG、PNG、MP4、PDF、DOCX…)直接存放,不再壓第二次 —— 對這些檔案再跑一次 deflate 只是花時間,省不到空間。
把檔案拖進來、給壓縮檔取個名字、下載一個 ZIP。全程沒有任何傳輸。在這個站的所有工具裡,這一個是「上傳」最明顯荒謬的一個 —— 把檔案裝進一個容器純粹是本機的檔案記帳,可是每一個線上壓縮服務都要你先把每一個檔案送給它們。
為什麼會有這一頁
想一下伺服器端的「製作 ZIP」服務實際上在做什麼。你上傳十個檔案,花掉你上傳頻寬允許的時間。伺服器把它們寫進一個容器 —— 這個操作不涉及任何分析、任何轉換、任何判斷。然後你下載結果,位元組數大約等於你剛剛傳上去的。為了完成一件完全不需要智慧的事,你的資料被完整搬運了兩次。
它會這樣運作的原因不是技術性的,而是那個網站是繞著伺服器建起來的,所以每件事都得經過伺服器。一旦運算改在瀏覽器裡發生,傳輸就消失了,而所有為了配給伺服器資源而存在的限制也一起消失:沒有單檔大小上限、沒有壓縮檔總量上限、沒有每小時次數、不用註冊。
當有人懷疑「瀏覽器裡的檔案工具是不是真的」時,這也是最適合拿出來指的一頁。這裡沒有任何轉換,所以沒有畫質可以爭論。位元組原樣出來、或者沒有 —— 而你可以自己解壓縮比對。
為什麼把照片壓成 ZIP 不會變小
ZIP 用一個叫 deflate 的演算法壓縮,原理是找出重複的位元組序列,把每一次重複換成一個短參照。這對文字、程式碼、CSV、XML、log,以及 BMP、WAV 這類未壓縮格式效果極好 —— 那些資料裡同樣的模式一直出現。
它對 JPG、PNG、WebP、MP4、MP3、PDF、DOCX 幾乎沒有作用,因為這些格式已經把自己的冗餘去掉了。它們的內容在統計上看起來像隨機雜訊,deflate 找不到任何東西可以壓。再壓一次通常會產生一個比輸入還大幾個位元組的檔案 —— 因為 deflate 必須加上自己的區塊標頭 —— 同時燒掉與檔案大小成正比的 CPU 時間。
這就是為什麼這裡預設是「自動判斷」:副檔名顯示已經是壓縮格式的檔案會直接存放,不再壓第二次,其餘走 deflate。檔案清單的每一列都告訴你這一筆得到哪一種處理,所以你看得到判斷依據,而不是納悶壓縮檔為什麼沒變小。DOCX、XLSX、PPTX、EPUB、APK、JAR 值得特別提一下 —— 那些本身就是換了副檔名的 ZIP 檔,這也是它們在直接存放清單上的原因。
實務上的結果是:如果你在打包二十張照片,ZIP 的大小大約就是那二十張照片。那不是失敗。把它們包成一個檔案好當成單一附件或單次上傳,本來就是目的;假裝不是這樣才是不誠實的部分。
中文檔名亂碼問題,以及它的來源
ZIP 裡的非 ASCII 檔名是一團真正的爛帳,而任何在繁體中文環境的人都撞過:你收到一個 ZIP、解開來,每一個檔名都是讀不出來的亂碼。
原因是歷史性的。最初的 ZIP 規範沒有規定檔名用哪一種字元編碼,所以各家工具就寫入當時機器的本地代碼頁 —— 台灣是 Big5、中國大陸是 GBK、日本是 Shift_JIS。一個用來宣告「這是 UTF-8」的欄位是很久以後才加上的,也就是 general purpose flag 的第 11 個位元。現代工具會設定它;舊的 Windows 工具、以及大約 2010 年以前寫的程式不會。當一個用 Big5 命名的壓縮檔被一個假設 UTF-8 的程式解開(或者反過來),每一個非 ASCII 字元都會變成雜訊。
這個工具把檔名寫成 UTF-8。那是正確的現代行為,也是 macOS、Linux、現行 Windows 與所有瀏覽器預期的。兩個誠實的但書:在中文版 Windows 上,非常舊的解壓縮軟體仍然可能讀錯,而那是「讀取端」的性質,不是壓縮檔能修的事;另外,如果你面對的是別人做出來的亂碼壓縮檔,任何壓縮工具都幫不上忙 —— 那需要一個重新編碼的工具。
如果一個檔案必須在「未知的收件人、未知的軟體」下存活,用 ASCII 檔名仍然是唯一有保證的答案。這是一個令人不滿意的結論,但它是真的;而先知道它,比在把五十個檔案寄給客戶之後才發現要好。
這個工具做什麼、不做什麼
重複的檔名會被處理,而不是默默吃掉。ZIP 的目錄是一份平面的名稱清單,兩筆一樣的名稱在技術上合法,但解壓縮時會互相覆蓋 —— 而你從兩個不同資料夾各拖一張 IMG_0001.JPG 進來,是完全可能發生的事。重複的名稱會被加上編號,而頁面會告訴你這件事發生了。
修改時間會沿用原始檔案,所以解壓縮之後日期不會全部變成「現在」。這對照片備份有差,因為日期是唯一大家實際使用的排序依據。
有三件事刻意不做。沒有資料夾 —— 全部平放進去,因為瀏覽器交給檔案輸入欄位的是一份檔案清單,不是它們原本的目錄結構。沒有密碼保護:ZIP 最初的加密 ZipCrypto 已經被破解、輕易就能破,而較強的 AES 變體是 PKWARE 的擴充,很多解壓縮軟體打不開;所以在這裡提供「密碼保護」等於賣一種安全感而不是安全。也沒有分卷壓縮 —— 那是軟碟時代的功能,現在多半只造成困惑。
限制:真實存在的與不存在的
我們沒有設任何限制。真正的約束是你裝置的記憶體,因為每個檔案都會被讀進記憶體,而完成的壓縮檔在下載前也放在那裡。桌機瀏覽器處理幾百 MB 很輕鬆。手機會更早放棄,而且失敗的樣子是分頁重新載入而不是一個清楚的錯誤訊息。
有一個格式限制值得知道:原始的 ZIP 格式用 32 位元的大小欄位,所以單一檔案與整個壓縮檔的上限是 4 GB。更大的壓縮檔需要 ZIP64 擴充。如果你已經接近那個邊界,你做的事本來就超出一個瀏覽器分頁該做的範圍,桌面軟體才是對的選擇。
引擎是 fflate —— 一個小型、MIT 授權、純 JavaScript 的實作,沒有 WebAssembly,而且這個站原本就用它把多檔結果打包。所以這一頁完全沒有新增任何依賴,而這件事本身就是一個關於「這份工作到底需要多少機器」的小論證。
常見問題
為什麼我的 ZIP 跟原本檔案一樣大?
因為那些檔案已經被壓縮過了。JPG、PNG、MP4、MP3、PDF、DOCX 早就把自己的冗餘去掉,deflate 找不到東西可以壓。但壓縮檔仍然讓你得到一個檔案而不是二十個 —— 那通常才是真正的目的。
中文檔名會不會變亂碼?
檔名是以 UTF-8 寫入的,macOS、Linux、現行 Windows 與瀏覽器都讀得正確。非常舊的解壓縮軟體仍然可能讀錯 —— 那是讀取端的限制,不是壓縮檔的問題。要寄給未知的收件人,ASCII 檔名是唯一的保證。
可以加密碼嗎?
刻意不提供。ZIP 最初的加密 ZipCrypto 已被破解、輕易可破;較強的 AES 變體是廠商擴充,很多解壓縮軟體打不開。在這裡提供它等於賣安全感而不是安全。
檔案數量或大小有上限嗎?
我們沒有設。實際的天花板是你裝置的記憶體,因為檔案是讀進分頁裡、壓縮檔也在那裡組成。另外要注意,傳統 ZIP 格式對單檔與整個壓縮檔的上限是 4 GB。
我要怎麼確認什麼都沒被上傳?
打開開發者工具切到 Network 分頁,做一個壓縮檔 —— 沒有任何請求夾帶你的檔案。你也可以在頁面載入之後把網路完全斷掉:它照樣能用,那是最簡單的證明。