ByteScope

Word 文件(docx)檔案格式

Office Open XML 格式的 Microsoft Word 文件。

MIME 類型
application/vnd.openxmlformats-officedocument.wordprocessingml.document
副檔名
.docx
分類
文件

Magic number(檔案簽章)

0x00000000504B0304PK··'PK' — it is a ZIP

ZIP 內含 '[Content_Types].xml' 以及一個 'word/' 目錄。

關於 Word 文件(docx)格式

.docx 是一個 Open Packaging Conventions 套件:一個普通的 ZIP 壓縮檔,裡面裝著 XML 元件與內嵌媒體,靠關聯檔案串在一起。把它改名成 .zip 打開,整份文件一覽無遺——word/document.xml 放文字與段落結構、word/styles.xml 放格式、word/media/ 放圖片。檔案前 30 個位元組裡沒有任何東西寫著「Word」;它的身分完全由 ZIP 目錄列出來的內容決定。

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

位移長度欄位意義
04Local file header signature50 4B 03 04。.docx 就是 ZIP,這是 ZIP 的第一個本地檔案標頭,和一般壓縮檔、.apk 或 .epub 開頭的那個一模一樣。讓這個檔案成為 Word 文件的東西,全都在更後面。
42Version needed to extract最低讀取端版本乘以 10,和 ZIP 所有整數一樣是小端序。deflate 是 20,Word 寫的就是這個;僅儲存的項目會出現 10。
62General purpose bit flag這裡最要緊的是位元 3:設起來的話,下面的 CRC 與兩個大小欄位都是 0,真正的數值改放在壓縮資料後面。Word 兩種都會寫,看它當時是不是以串流方式輸出。
82Compression method.docx 幾乎每個元件都是 8,也就是 deflate,因為 XML 壓縮效果極好——一頁文字是好幾 KB 的 XML,落到磁碟上只剩幾百個位元組。已經壓過的媒體則可能用方法 0 直接存。
102Last modified timeMS-DOS 打包的時間——5 位元時、6 位元分、5 位元的兩秒刻度。Word 會把自己產生的元件時間戳記正規化,所以這裡幾乎不代表文件真正的編輯時間;真正的日期在 docProps/core.xml。
122Last modified dateMS-DOS 打包的日期,7 位元年份(從 1980 起算)、4 位元月、5 位元日。1980 年以前表達不出來,也沒有時區。
144CRC-32這個元件未壓縮內容的檢查碼。它只涵蓋單一項目,所以 .docx 完全可能第一個元件 CRC 正確,第三個元件就壞了。
184Compressed size標頭與可變長度欄位之後的 deflate 資料位元組數。FF FF FF FF 代表要去看 ZIP64 額外欄位,.docx 實務上根本用不到。
224Uncompressed size元件的原始長度。[Content_Types].xml 大約是幾百到幾千個位元組;它和壓縮後大小的比例通常好過 5 比 1。
262File name length只要第一個項目是 [Content_Types].xml——Word 和其他 OOXML 寫入端都是先吐這個——這裡就是 13 00,也就是 19 個位元組。這是整個檔案裡第一個透露出「你手上拿的是什麼」的欄位。
282Extra field lengthWord 寫出來的套件通常是 0。非零值代表帶了 ZIP64 大小、Unix 權限或高精度時間戳記,那是重新打包的工具加的,不是 Word。
3019First entry nameASCII 的 [Content_Types].xml。這個元件是整個套件的地圖:它替壓縮檔裡每個副檔名與每個覆寫項目標出內容型別,OPC 規定它必須放在套件根目錄。它出現在位移 30,是判定「這是某種 OOXML」最省事的正面測試。
variablevariableword/document.xml讓這個套件成為 Word 文件、而不是活頁簿或簡報的元件。它不在固定位移——要透過檔尾的中央目錄去找——但它的名稱出現在目錄裡就是決定性的判準,旁邊還有把它連到圖片與樣式的 word/_rels/document.xml.rels。
-224End of central directory signature50 4B 05 06,在沒有壓縮檔註解時位於倒數第 22 個位元組。讀取端從這裡起步,走它指向的中央目錄,然後才知道套件裡有哪些元件——所以第一個標頭健康、尾巴掉了的 .docx,根本打不開。
-64Offset of the central directory中央目錄開始的絕對位元組位置,同樣以「沒有註解」為前提。只要在檔案前面加東西,這個數字的基準就錯了,下載來的文件會跳「Word 無法開啟這個檔案」,機制大多就是這個。

怎麼跟長得像的格式分開

容易搞混的怎麼分
Excel 活頁簿(xlsx)整個本地檔案標頭逐位元組相同,通常連第一個項目名稱也相同,因為兩者位移 30 都是 [Content_Types].xml。唯一可靠的分界是檔尾的目錄:活頁簿會列出 xl/workbook.xml 和一棵 xl/ 樹,文件則是 word/document.xml 和一棵 word/ 樹。內容型別元件本身也會指名是哪一種,在一個 ContentType 結尾為 wordprocessingml.document 的 Override 裡。
ZIP.docx 就是 ZIP——問題從來不是「是不是」,而是「是哪一種」。一般壓縮檔完全沒有必備的項目名稱,所以測試要用正面的:找根目錄下的 [Content_Types].xml 加上一個 _rels/.rels 元件。兩者缺一,那就只是一個剛好裝了些 XML 的 ZIP。
OLE2 / CFB.docx 取代掉的那個格式。Word 97-2003 的 .doc 是 Compound File Binary 容器,開頭 D0 CF 11 E0 A1 B1 1A E1,裡面有一個名字就叫 'WordDocument' 的串流;.docx 開頭是 50 4B 03 04。兩者都能用同一套 Word 打開,而 Word 是讀位元組決定的,不是看副檔名——所以標錯副檔名的檔案照樣打得開,標對卻壞掉的反而打不開。
EPUB兩者都是裝著標記語言的 ZIP 套件,也都會被只看到 'PK' 就收工的粗糙偵測器搞混。EPUB 把第一個項目釘得死死的——'mimetype',未壓縮儲存、不得有額外欄位,位移 38 是 application/epub+zip——OOXML 在位元組層級什麼都沒釘,只能靠項目名稱辨識。位移 30 讀到 'mimetype' 的話,你手上的就不是 .docx。
docm啟用巨集的 Word 文件,在 hex 編輯器會看的每個地方都和 .docx 逐位元組相同。差別在裡面多一個 word/vbaProject.bin 元件,以及 [Content_Types].xml 裡不同的 ContentType。來路不明的檔案值得查的就是這一對,因為看得到的差別只有副檔名,而改名不費吹灰之力。

常見的壞法

  • 尾巴不見了。每個本地標頭、每個壓縮元件都可能完好無缺,檔案卻打不開,因為 ZIP 讀取端是從 end-of-central-directory 記錄起步的,而它沒了。救援方式是往後掃 50 4B 03 04,從本地標頭重建目錄,對 .docx 來說通常能把文字完整救回來。
  • 前面被塞了位元組。一頁 HTML 錯誤頁或 PHP 警告被存成 .docx,整個檔案就位移了,中央目錄裡的絕對位移現在通通指到錯的地方。Word 會回報檔案損毀,但整份文件其實都還在;把 50 4B 03 04 前面的東西刪掉就好了。
  • 文字模式傳輸。deflate 資料流裡的換行被轉換過,所有標頭欄位讀得出來、項目名稱也都正確,所以套件列得漂漂亮亮,然後 Word 解壓縮 word/document.xml 時卡在 CRC 不符。這個失敗看起來很像 Word 的 bug,其實不是。
  • 元件被手改過又重新打包錯了。因為元件就是純 XML,改起來很容易,錯就錯在重新壓縮這一步:替資料夾本身也加一筆目錄項目、改動項目名稱的大小寫、或在 XML 宣告前面塞了 BOM,都會讓 Word 拒收這個套件,而每個 ZIP 工具都說它很健康。
  • word/media 底下的元件被截斷。圖片是以一般 ZIP 項目儲存的,所以套件裡有一張只寫了一半的 PNG,文件文字完全完好可讀,只是那張圖變成一個破圖佔位。CRC 失敗的就只有那一個項目,其他都沒事。

這個格式現在還在用嗎

.docx 套件是各處預設的文書處理格式,而且以微軟的格式來說很難得,它是貨真價實的開放標準——ECMA-376 與 ISO/IEC 29500——所以 Google Docs、LibreOffice 和 Apple Pages 都讀寫得有模有樣。從二進位 .doc 換過來,換到了兩件在微軟之外也有意義的事:可救回性,因為文字就是純 XML,套件壞掉也還活著;還有體積,壓縮過的 XML 比裝同樣內容的 compound file 小得多。它沒解決的是不同實作之間的保真度——標準大得驚人、各個元件互相牽扯很深,一份文件在非微軟的編輯器裡繞一圈回來,行距、編號或清單縮排常常會有微妙的差異。所以要協同編輯、要用追蹤修訂審閱的東西,.docx 是首選;而外觀在每台機器上都必須一模一樣的東西,它是錯的選擇,那是 PDF 的工作。它實務上的缺點是:一個裝滿 XML 的 ZIP 是很誘人的投放載體,啟用巨集的兄弟格式 .docm 在位元組層級像到郵件過濾器非得把每個套件拆開看,不能相信副檔名。

在這個站上打開 Word 文件(docx)檔

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

相關格式

容易和 Word 文件(docx)搞混的格式,可以比對它們的開頭位元組。

格式開頭位元組副檔名
Excel 活頁簿(xlsx)50 4B 03 04.xlsx
PowerPoint 簡報(pptx)50 4B 03 04.pptx
ZIP50 4B 03 04.zip
OLE2 / CFBD0 CF 11 E0 A1 B1.doc
EPUB50 4B 03 04.epub

常見問題

檔案的 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 仍然可能夾帶惡意內容。辨識真實類型是有用的第一道檢查,尤其在副檔名和位元組不一致的時候,但它不是惡意軟體掃描。

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