chm格式簡介
chm格式有乙個初始化頭,佔38個位元組,後面是header section和到正文的偏移量。加在一起,這些被稱為檔案頭。
header section一共有兩個section(有點像資訊說明),乙個是檔案目錄,另乙個包含著檔案長度和一些未知資訊。
檔案頭
檔案頭包含初始化資訊,格式如下:
0000:第乙個雙字為itsf
0004:第二個雙字為版本資訊
0008:第三雙字是檔案頭的總長度
000c:第四雙字值為1
0010:第五雙字是乙個時間記錄 (第乙個位元組是msb,第二個位元組是 fractional seconds(second byte),第三個位元組可並不確定,第四個位元組僅能知道其符號位是確定的。
0014:第六雙字是windows語言id標識
後面16個位元組是兩個連續的guid,分別為
0018:
0028:
後面是header section的表,其中有兩項,每項佔16個位元組,記錄著從檔案頭開始的偏移量和section的長度,各佔8個位元組。
0000:從檔案起始處開始的section偏移量
0008:section的長度
後面還有8個位元組的資訊,這些在版本2裡是沒有的。這個資訊是附加頭資料。
header section
header section 0:
0000:第一雙字0x01fe(未知)
0004:第二雙字0(未知)
0008:第三雙字為檔案大小
0010:第四雙字0(未知)
0014:第五雙字0(未知)
header section 1(目錄列表)
chm檔案的中心部分,檔案目錄和檔案資訊。它包含如下部分:
0000:第乙個雙字為itsp,
0004:第二個雙字為版本號為1,
0008:第三雙字為目錄頭長度,
000c:第四雙字為0a資訊未知,
0010:第五雙字值為0x1000,是目錄塊的大小,
0014:第六雙字是quickref section的「密度」,一般是2
0018:第七雙字是索引樹的深度,1表示沒有索引,2表示有一層的pmgi資料塊。
001c:第八雙字表示根索引的塊號,如果沒有索引為-1
0020:第九雙字是第乙個pmgl(listing)的塊號
0024:第十雙字是最後乙個pmgl的塊號
0028:第十一雙字是-1(未知)
002c:第十二雙字是目錄塊的塊數
0030:第十三雙字是windows語言id標識
0034:從這裡開始有16個位元組的guid
0044:接著的雙字是54(又乙個長度)
0048:雙字都為-1(未知)
004c:雙字都為-1(未知)
0050:雙字都為-1(未知)
列表塊
檔案頭後就是目錄塊。目錄塊分為兩種,一種是列表塊(listing chunks),一種是索引塊(index chunks)。如果只有乙個列表塊,則索引塊被省略。
其中列表塊的格式如下:
0000:開始是四個位元組pmgl
0004:然後的四個位元組是目錄塊尾部的空白區的長度或是quickref區域的長度
0008:第三雙字總為0
000c:第四雙字是前乙個列表塊的塊號,如果這是第乙個塊,該值為-1
0010:第五雙字是後乙個列表塊的塊號,如果這是最後一塊,該值為-1
0014:從這裡開始是目錄列表項,按檔名排序,並且大小寫不分
quickref區是從資料塊的後面向前寫,每隔n個項出現乙個quickref,且n的值為1+(1<<「密度」),其格式從後至前為。例如密度為2,n為5。
塊長度-0002:第乙個字:整個資料塊中的入口數
塊長度-0004:第二個字:從第0項到第n項之間的偏移量
塊長度-0008:第三個字:從第0項到第2n項之間的偏移量
塊長度-000c:第四個字:從第0項到第3n向之間的偏移量
以此類推
目錄列表的每一項入口的格式如下:
byte:encint型名字長度
bytes:後面是utf-8編碼的名稱
encint:encint型正文段
encint:encint型偏移量
encint:encint型長度
其中偏移量是從解壓縮之後的正文段的開始來計算的,同樣長度也是表示解壓縮之後的長度。
在目錄中存在兩種檔案,使用者資料檔案和格式資訊檔案,格式資訊檔案以兩個連續的冒號「::」開頭,使用者資料檔案以「/」開頭。
索引塊
索引塊的格式如下:
0000:前四個位元組為pmgi
0004:後面四個位元組是塊尾部的quickref或是空白區的長度。
0008:從這裡開始是目錄索引項的開始,
quickref的格式和排列與列表塊中相同。
每乙個目錄索引項的結構如下:
byte:encint型的名稱長度
bytes:uft-8編碼的名稱
encint:以此名稱開始的列表塊的塊號。
當有索引塊的層次較多時,將不再儲存資料塊號而是儲存下一層的索引號。
解釋一下encint型變數的編碼規則:
一種可變長度的整型變數,第乙個位元組只使用低7位,最高位為1表示該位元組之後的下一位元組的低7位要接在這7位的尾部組成乙個數,這樣通過移位相加的運算,直到遇到最高位為0的位元組,可以組和成乙個長度可調節的整數。
正文
在版本3中,正文一般緊跟著檔案頭,而且在檔案頭表之後有乙個雙字用來指定其位置。在版本2中,正文部分緊跟著檔案頭。所有第0段正文內容在目錄中的位置都是相對那點來說的,其它的正文段都在content section 0中。
名稱列表檔案
放在content section 0和目錄中的檔案,檔名為"::dataspace/namelist",其中包含著所有正文段的名稱,其格式如下:
0000:第乙個字:以字計數的檔案長度
0002:第二個字:檔案中的entry數
對於每乙個entry格式為:
0000:第乙個字:以字計數的名字長度,不包括最後的null結尾符
0002:以word 0表示所有entry的結束。
***x:字0
名稱的編碼類似於uft-16。
段的名稱目前為止只有兩種,uncompressed和mscompressed,分別表示自解釋檔案和microsoft lzx壓縮演算法壓縮的檔案。
section data
對於段號不為0的段,還有乙個檔案為::dataspace/storage//content,裡面存放著該段的壓縮資訊,所以,當解析
非0段時,需要兩步工作,第一步,取得第0段並將其解圧,取得段名,第二步才能利用段名找到相應的段
其餘與格式相關的檔案
::dataspace/storage//controldata
共0x20個位元組,儲存關於壓縮的資訊
0000:第乙個雙字為在「lzxc」串後的雙字個數,在版本2中,此值必為6
0004:ascii第二個雙字為「lzxc」
0008:第三個雙字為版本資訊,必須大於2
000c:第四個雙字為lzx reset interval(0x8000字大小的塊中)
0010:第五個雙字為視窗大小.
0014:第六個雙字為快取大小
0018:第七個雙字為0,未知資訊。
001c:第八個雙字為0,未知資訊。
::dataspace/storage//spaninfo)
存放著未解壓的段的長度資訊。
::dataspace/storage//transform/list
存放guid列表用於解壓縮
附錄:壓縮說明
這一段用lzx壓縮,要進行解壓縮,先要讀取::dataspace/storage//transform/
/instancedata/resettable,其格式如下:
0000:第乙個雙字為2,估計是版本資訊
0004:第二個雙字是reset table中的entry數
0008:第三個雙字是8,每乙個entry的大小
000c:第四個雙字是表頭長度
0010:16個位元組的壓縮前長度
0018:16個位元組的壓縮後長度
0020:16個位元組的0x8000 block size for locations below
0028:16個位元組的0
0030:16個位元組的第乙個非壓縮資料塊的邊界在壓縮資料塊中的位置資訊
現在你就已經了解了整個
chm檔案格式。
epub格式電子書剖析
1 檔案 mimetype 每一本epub電子書均包含乙個名為mimetype的檔案,且內容不變,用以說明epub的檔案格式。檔案內容如下 2 目錄 meta inf 依據ocf規範,meta inf用於存放容器資訊,預設情況下 即加密處理 該目錄包含乙個檔案,即container.xml,檔案內容...
epub電子書格式簡介
epub是國際開放電子圖書聯盟 open ebook forum oebf 於 1999 年推出了用來表示電子圖書的內容 結構的一種開放性規範,旨在統一電子書的格式和提公升電子書的相容性。目前 oebf 已改名為 idpf international digital publishing forum...
epub電子書格式簡介
epub是國際開放電子圖書聯盟 open ebook forum oebf 於 1999 年推出了用來表示電子圖書的內容 結構的一種開放性規範,旨在統一電子書的格式和提公升電子書的相容性。目前 oebf 已改名為 idpf international digital publishing forum...