ByteScope

RAR(4.x)檔案格式

採用 RAR 1.5–4.x 格式的 RAR 壓縮檔。

MIME 類型
application/x-rar-compressed
副檔名
.rar
分類
壓縮與封存

Magic number(檔案簽章)

0x00000000526172211A0700Rar!···'Rar!' RAR4 signature

關於 RAR(4.x)格式

RAR 4.x 是舊版 WinRAR 格式,由 WinRAR 1.5 到 4.20 產生,今天只要指定「相容性優先」也還是會吐出這種檔案。檔案裡的一切都是區塊,每個區塊開頭都是同樣四個欄位——16 位元 CRC、1 位元組型別、16 位元旗標、16 位元大小——這也是為什麼位移 0 的那 7 個位元組標記本身就是一個區塊,而不是單純的 magic number。這個格式是專有的:解壓縮演算法有公開,壓縮演算法沒有,所以自由軟體讀得了 RAR 4,卻寫不出來。

檔頭結構,一個位元組一個位元組看

位移長度欄位意義
07Marker block (MARK_HEAD)永遠是 52 61 72 21 1A 07 00,讀起來是 'Rar!' 後面接 1A 07 00。它不是單純的 magic number,而是一個內容剛好固定的正規 RAR 區塊:HEAD_CRC 0x6152、HEAD_TYPE 0x72、HEAD_FLAGS 0x1A21、HEAD_SIZE 0x0007。RAR5 保留前 6 個位元組再接上 01 00,所以位移 6 那個位元組就是兩個世代的全部差別。
72Archive header CRC (HEAD_CRC)對這個區塊剩餘內容取 CRC-32 之後的低 16 位元。每個 RAR 區塊都帶一個,所以在 hex 編輯器裡可以把損壞定位到單一區塊,不必判整個壓縮檔死刑。
91Archive header type (HEAD_TYPE)0x73 代表 MAIN_HEAD,也就是整個壓縮檔層級的標頭。其他會遇到的型別是 0x74 檔案、0x75 註解、0x7A 子區塊、0x7B 壓縮檔結尾標記。
102Archive header flags (HEAD_FLAGS)小端序位元欄位。0x0001 表示這是集合中的一卷、0x0002 表示內嵌了壓縮檔註解、0x0004 表示已鎖定不可修改、0x0008 solid、0x0010 使用較新的 name.partN.rar 分卷命名、0x0040 有修復記錄、0x0080 連區塊標頭本身都加密、0x0100 這是第一卷。
122Archive header size (HEAD_SIZE)這個區塊的總長度,包含已經讀掉的那 6 個位元組。單純的情況是 0x000D,也就是 13 個位元組,下一個區塊從位移 20 開始;如果內嵌了註解或真實性記錄就會變大,後面所有東西跟著往後推。
142RESERVED1保留欄位,所有已發行版本都寫 0。歷史上在很舊的版本裡曾經放過卷號的高位字組。
164RESERVED2保留欄位,寫 0。這 4 個位元組的填補讓壓縮檔標頭維持在大家熟悉的 13 位元組長度。
202First file header CRC第一個 FILE_HEAD 區塊的開頭——但前提是上面那個壓縮檔標頭剛好是最小的 13 位元組。請讀位移 12 的 HEAD_SIZE 再加上 7,不要無條件相信 20;下面每一列的位移都繼承同樣的假設。
221File header type (HEAD_TYPE)0x74。如果這裡看到的是 0x7B,代表壓縮檔是空的,因為那是壓縮檔結尾區塊。
232File header flags0x0001 代表這個檔案是從前一卷接續下來的、0x0002 代表它會延續到下一卷、0x0004 代表有密碼保護、0x0100 代表有 64 位元大小的高位字組、0x0200 代表檔名除了本地字碼頁之外還存了一份 UTF-16、0x0400 代表檔名後面跟著 8 位元組的 salt。
252File header size (HEAD_SIZE)整個標頭的長度,也就是 32 個位元組的固定欄位加上檔名,再加上選用的 salt 或延伸時間戳記。壓縮資料緊接在它後面開始。
274PACK_SIZE這個項目壓縮後的位元組數,低 32 位元。超過 4 GiB 的檔案會把高位字組另外放在 ATTR 欄位後面,而且只在旗標 0x0100 有設時才存在。
314UNP_SIZE原始位元組數,低 32 位元,超過 4 GiB 的處理方式同上。solid 壓縮檔即使單獨解不開這個項目,這裡照樣記著真正的數值。
351HOST_OS建立這個項目的系統:0 MS-DOS、1 OS/2、2 Windows、3 Unix、4 Mac OS、5 BeOS。它決定下面那 4 個屬性位元組該怎麼解讀。
364FILE_CRC未壓縮內容的 CRC-32。WinRAR 每次報「checksum error」講的都是這個數字,也正是修復記錄想幫你救回來的東西。
404FTIMEMS-DOS 打包過的日期時間:7 位元年份(從 1980 起算)、4 位元月、5 位元日,接著 5 位元時、6 位元分、5 位元的兩秒刻度。沒有時區、解析度兩秒、1980 年以前的時間表達不出來。
441UNP_VER最低解壓縮器版本乘以 10。20 代表 2.0 演算法,29 代表 WinRAR 3.x 與 4.x 用的 2.9 版。現代解壓縮工具全部都實作了;這個位元組只有在舊工具拒絕開檔時才有意義。
451METHOD0x30 僅儲存、0x31 最快、0x32 快速、0x33 標準、0x34 較佳、0x35 最佳。0x30 的項目可以從損壞的壓縮檔裡手動挖出來,因為標頭後面那些位元組就是檔案本身。
462NAME_SIZE固定欄位之後那段檔名的位元組長度。旗標 0x0200 有設時,這段先放本地字碼頁的檔名,接一個 0 位元組,然後是同一個檔名壓縮過的 UTF-16 形式。
484ATTR檔案屬性,依 HOST_OS 解讀:Windows 上是 DOS 屬性位元,Unix 上是一個 Unix mode 值。RAR 就是用這裡的目錄位元標記資料夾項目,那種項目完全沒有資料。
52variableFILE_NAMENAME_SIZE 個位元組的路徑,用反斜線而不是斜線。檔名開頭是磁碟機代號、或路徑裡含 .. 的項目就是路徑穿越攻擊,正常的解壓縮工具都會拒絕。

怎麼跟長得像的格式分開

容易搞混的怎麼分
RAR5兩個世代共用 6 個位元組,第 7 個分家。RAR 4 是 7 位元組的 52 61 72 21 1A 07 00;RAR 5 是 8 位元組的 52 61 72 21 1A 07 01 00。兩者副檔名都是 .rar、都出自 WinRAR,所以位移 6 那個位元組是「2005 年的工具打得開」和「打不開」之間唯一的分界。往裡面看,RAR 5 把整個區塊配置換成可變長度整數,標記以下沒有任何東西能互通。
ZIP位元組層級毫無懸念——52 61 72 21 對上 50 4B 03 04——但兩者被搞混的頻率高得驚人,因為在使用者眼中都是「壓縮資料夾」。真正重要的是結構差異:ZIP 把目錄放在檔尾,讀最後幾百個位元組就能列出內容;RAR 則是從檔頭一路走區塊鏈,所以尾端被截斷的 RAR 照樣列得出清單,ZIP 不行。
7-Zip7-Zip 壓縮檔開頭是 37 7A BC AF 27 1C。兩種格式都提供 solid 壓縮與強力加密,而且 7-Zip 這個程式兩種都寫得出來,混淆就是從這裡開始的。.7z 格式開放、可自由實作;RAR 的壓縮不是,所以做得出 .7z 的工具不代表做得出 .rar。
Self-extracting RARSFX 壓縮檔是一個把 RAR 資料附在後面的 Windows 執行檔,所以位移 0 讀到的是 4D 5A('MZ'),'Rar!' 標記要往後幾千個位元組才出現。它仍然是完全有效的壓縮檔:拿真正的解壓縮工具指向它,工具會往後掃標記,不會堅持要在位移 0 找到。

常見的壞法

  • 多卷集合裡少了一卷。每一片本身都是格式正確的 RAR,所以 hex dump 看到的是完好的標記與乾淨的區塊 CRC,解壓縮卻還是失敗,因為某個標了 0x0002 的項目要延續到一個根本不在的分片。判斷方式是位移 10 的壓縮檔標頭旗標有 0x0001,而 .partN.rar 的編號中間有缺口。
  • 下載被截斷。RAR 從位移 7 開始往前走區塊,所以截斷點以前的東西都能正常解出來,只有最後一個項目會失敗。如果有修復記錄——壓縮檔標頭旗標 0x0040——WinRAR 能重建的量出乎意料地多,這也是 RAR 相對 ZIP 唯一保住的實質優勢。
  • 文字模式傳輸。FTP 用戶端開在 ASCII 模式會改寫壓縮資料流裡的每一組 0D 0A,而標記與所有標頭位移都毫髮無傷。壓縮檔列得漂漂亮亮,然後每個項目都卡在位移 36 的 FILE_CRC——這正是常被誤判成「密碼錯了」的症狀。
  • 標頭加密被當成損壞。用 -hp 時連區塊標頭都是加密的,所以位移 20 之後的 hex dump 是一片雜訊,檔名永遠不會出現。位移 10 的壓縮檔標頭旗標 0x0080 就是拿來和真正的損壞區分的,而且這種檔案其實完好無缺。
  • 區塊標頭裡有一個位元組被翻掉。因為位移 25 的 HEAD_SIZE 是在告訴讀取端下一個區塊從哪開始,這個欄位壞掉毀的不是一個項目——而是整條走訪路線出軌,後面每個區塊都從錯的位置開始讀。16 位元的 HEAD_CRC 就是在讀取端跑掉之前攔下它的東西。

這個格式現在還在用嗎

RAR 4 是靠慣性、外加一項真材實料的技術優勢活下來的舊格式。慣性佔比較大:1998 到 2012 年間流出的 scene release、老備份、大量網路上的東西,都是 RAR 4 多卷集合,而且沒有人會回頭重打包。技術優勢是修復記錄,它能讓壓縮檔撐過光碟片的位元衰減或是不穩定的傳輸,這件事 ZIP、7z、tar.gz 通通做不到。至於新建的壓縮檔,它在其他每個面向都輸了:7-Zip 和 Zstandard 壓得更好又開放,而 RAR 的壓縮演算法仍然是專有的,所以流程裡如果會產出 .rar,等於把自己綁在單一廠商的工具上。RAR 5 在 2013 年接班,帶來 64 位元大小、更好的加密和更快的修復記錄,WinRAR 現在預設就寫 RAR 5——RAR 4 是你明知對方解壓縮工具很舊,才刻意去選的選項。

在這個站上打開 RAR(4.x)檔

這些全部在你的瀏覽器裡跑,檔案不會離開你的電腦。

相關格式

容易和 RAR(4.x)搞混的格式,可以比對它們的開頭位元組。

格式開頭位元組副檔名
RAR552 61 72 21 1A 07.rar
7-Zip37 7A BC AF 27 1C.7z
ZIP50 4B 03 04.zip

常見問題

檔案的 magic number 是什麼?

檔案開頭的前幾個位元組,不管檔名寫什麼,它標明的是真正的格式。PNG 一定以 89 50 4E 47 開頭,ZIP 則是 50 4B 03 04。作業系統、瀏覽器和 file 指令讀的都是這幾個位元組,而不是相信副檔名 — 這就是為什麼把檔案改名並不會改變它實際上是什麼。

我要怎麼自己檢查 magic number?

在 macOS 或 Linux 上,xxd -l 16 檔名 會印出前 16 個位元組;在 Windows 上,PowerShell 的 Format-Hex -Path 檔名 -Count 16。或者把檔案丟進本站的檔案類型辨識工具,它會在本機讀取位元組並告訴你是什麼格式,不會上傳任何東西。

為什麼兩種格式的 magic number 會一樣?

因為其中一種是建立在另一種之上。docx、xlsx、pptx、apk、jar 與 epub 骨子裡都是 ZIP 壓縮檔,所以全都以 ZIP 的簽章開頭;要分辨它們得看裡面的項目。Java class 檔和 macOS 的通用二進位檔都以 CA FE BA BE 開頭,靠緊接其後的欄位區分。

有完全沒有 magic number 的檔案嗎?

有。XML、HTML、JSON、SVG、CSV 這類以文字為基礎的格式沒有固定的位元組簽章,所以改用結構來辨識:開頭的 <?xml 宣告、<svg 元素,或是 { 後面接著帶引號的鍵。這種偵測是合理推測而非確定,因此本參考頁會把這些格式標示為結構偵測。

magic number 相符就代表檔案安全嗎?

不代表。它告訴你的是格式,不是內容是否無害 — 一個貨真價實的 PDF 或 docx 仍然可能夾帶惡意內容。辨識真實類型是有用的第一道檢查,尤其在副檔名和位元組不一致的時候,但它不是惡意軟體掃描。

手上有檔案可能是 RAR(4.x)?用檔案類型辨識工具查出來 — 它在本機讀取 magic number,不上傳任何東西。或者瀏覽所有格式。