聲明:本文并非百分百原創,乃是對兩位前輩已有工作的補充與完善,兩位前輩的成果在參考鏈接里。
參考鏈接: http://wenku.baidu.com/view/3caf8f11866fb84ae45c8de5.html ? rar文檔結構分析
????????????????? http://wenku.baidu.com/view/b7889b64783e0912a2162aa4.html ? RAR文件格式的研究
本文已上傳,下載鏈接為: http://download.csdn.net/detail/ping_fani07/5353575
?
?
?
? ? RAR?version?3.40?-?Technical?information
RAR 3.40版??????????? 技術信息????????????
??~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
?THE?ARCHIVE?FORMAT?DESCRIBED?BELOW?IS?ONLY?VALID?FOR?VERSIONS?SINCE?1.50
??
下面對歸檔文件格式的描述僅僅是對
1.5
以后的版本是有
效的
?
?
?=======================================================================================================
RAR?archive?file?format
RAR歸檔文件格式
?=======================================================================================================
??Archive?file?consists?of?variable?length?blocks.?
???? ?歸檔文件是由可變長度的塊組成的。
??The?order?of?these?blocks?may?vary,?but?the?first?block?must?be?a?marker?block?followed?by?an?archive?header?block.
??? ?
?這些塊之間沒有固定地先后順序,但是要求第一個塊必須是被一個歸檔頭部塊緊跟的標志塊
????? 【譯者注:即第一個塊是標志塊,并且其后緊跟一個歸檔頭部塊】。
???Each?block?begins?with?the?following?fields:
????????
每一個塊都是由以下域開始的:
【譯者注:即每一個塊的頭部都是由以下域(可稱之為頭域)組成的】
HEAD_CRC???????2?bytes?????CRC?of?total?block?or?block?part
????????????????????????????????????????????????
整個塊或者塊某個部分的CRC(根據塊類型而有不同)
?
HEAD_TYPE??????1?byte??????Block?type
????????????????????????????????????????????????
塊類型
【譯者注:也可以理解為塊頭部類型,因為不同的塊對應不同的塊頭部。后文也經常混淆這兩種概念。】
HEAD_FLAGS??? 2?bytes?????Block?flags
???????????????????????????????????
?????????????塊標志
HEAD_SIZE????????2?bytes?????Block?size
????????????????????????????????????????????????
塊大小
【譯者注:本文中和塊頭部大小的概念一直混淆。后文中當遇到標志塊、結尾塊等只有頭部的塊時,也可理解為塊頭部大小】
ADD_SIZE??????????4?bytes?????Optional?field?-?added?block?size
???????????????????????????????????
?????????????添加塊的大?。ㄟ@是一個可選域)
????? Field?ADD_SIZE?present?only?if?(HEAD_FLAGS?&?0x8000)?!=?0
???????
頭域ADD
_SIZE僅當(
HEAD_FLAGS?&?0x8000)?!=?0
【譯者注:即塊標志的首位被置
1
】
的時候才會存在
???? Total?block?size?is?HEAD_SIZE?if?(HEAD_FLAGS?&?0x8000)?==?0
????????
當(
HEAD_FLAGS?&?0x8000)?==?0
【譯者注:即塊標志的首位被置
0
】
的時候,整個塊的大小就是HEAD_SIZE
?????and?HEAD_SIZE+ADD_SIZE?if?the?field?ADD_SIZE?is?present?-?when?(HEAD_FLAGS?&?0x8000)?!=?0.
????????
而當(
HEAD_FLAGS?&?0x8000)?!=?0
【譯者注:即塊標志的首位被置
1
】
的時候,整個塊的大小就是(HEAD_SIZE+ADD_SIZE)
???In?each?block?the?followings?bits?in?HEAD_FLAGS?have?the?same?meaning:
??????
HEAD_FLAGS域【塊標志】的以下幾位在每一個塊中都有相同的含義:
??0x4000?-?if?set,?older?RAR?versions?will?ignore?the?block?and?remove?it?when?the?archive?is?updated.
???【高二位】??
(此位)如果置為
1
,老版本的
rar
會在
歸檔文件更新的時候忽略這個塊,并且移除這個塊。
????????????????? ?if?clear,?the?block?is?copied?to?the?new?archive?file?when?the?archive?is?updated;
?????????????????????????
如果清為
0
,那么當更新的時候,這個塊會被復制到新的歸檔文件中
??0x8000?-?if?set,?ADD_SIZE?field?is?present?and?the?full?block?size?is?HEAD_SIZE+ADD_SIZE.
???【最高位】??
(此位)如果置為
1
,就會存在ADD_SIZE這個域,并且整個塊的大小就應該是(HEAD_SIZE+ADD_SIZE)
??Declared?block?types:
????
?? 已經聲明過的塊類型包括:
HEAD_TYPE=0x72??????????marker?block【譯者注:有些文獻里也稱之為
MARK_HEAD
】
????????????????????????????????
???????????標志塊
【譯者注:一個固定為0x52?61?72?21?1A?07?00的7字節序列】
HEAD_TYPE=0x73??????????archive?header【譯者注:有些文獻里也稱之為
MAIN_HEAD
】
????????????????????????????????
???????????
歸檔頭部塊
HEAD_TYPE=0x74??????????file?header【譯者注:有些文獻里也稱之為
FILE_HEAD
】
???????????????????????????????
??
??????????
文件塊
【譯者注:直譯為文件頭部,但是此處的類型應該指的是整個塊的類型,而非塊頭部結構的類型,因此感覺稱之為文件塊更合適。】
HEAD_TYPE=0x75??????????old?style?comment?header
????????????????????????????????
???????????
老風格的?注釋塊
【譯者注:直譯為注釋頭部,基于和文件塊一樣的原因,感覺稱之為注釋塊更合適】
HEAD_TYPE=0x76??????????old?style?authenticity?information
?????????????????????????????????
??????????
老風格的?授權信息塊
/
用戶身份信息塊
HEAD_TYPE=0x77??????????old?style?subblock
?????????????????????????????????
??????????
老風格的?子塊
HEAD_TYPE=0x78??????????old?style?recovery?record
?????????????????????????????????
??????????
老風格的?恢復記錄塊
HEAD_TYPE=0x79??????????old?style?authenticity?information
?????????????????????????????????
??????????
老風格的?授權信息塊
/
用戶身份信息塊
HEAD_TYPE=0x7a??????????subblock
???????????????????????????????
??
??????????
子塊
HEAD_TYPE=0x7b??????????end?block
?????????????????????????????????
???????????
結束塊
【譯者注:一個固定為0xC4?3D?7B?00?40?07?00的7字節序列】
???Comment?block?is?actually?used?only?within?other?blocks?and?doesn't?exist?separately.
???????
注釋塊實際上只在其它塊中使用,并不單獨存在
???Archive?processing?is?made?in?the?following?manner:
?????? ?
歸檔
文件的處理遵循以下流程:????
1.?Read?and?check?marker?block
????
讀取和檢查標志塊
【譯者注:確認這是一個
rar
格式的歸檔文件】
2.?Read?archive?header
????
讀取歸檔頭部塊的信息
3.?Read?or?skip?HEAD_SIZE-sizeof(MAIN_HEAD)?bytes
????
讀取或者是跳過HEAD_SIZE(?即sizeof(MAIN_HEAD)?)個字節的內容
【譯者注:即跳過歸檔頭部塊,將指針指向下一個塊,也就是文件塊的開始位置,然后讀取緊接下來的 7 字節。另外,譯者覺得句首的“讀取”不知所云,第二步明明已經讀取,此步應該只要跳過就好。 】
4.?If?end?of?archive?encountered?then?terminate?archive?processing,
???
如果遇到歸檔文件結束標志
【譯者注:即下一個塊是結束塊】,
那么終止歸檔文件處理過程,
??? else?read?7?bytes?into?fields?HEAD_CRC,?HEAD_TYPE,?HEAD_FLAGS,?HEAD_SIZE.
????
不然的話,讀取7
個字節
到頭部的四個域:HEAD_CRC
,
HEAD_TYPE
,
HEAD_FLAGS
,
HEAD_SIZE
?中。
5.循環處理?
?????Check?HEAD_TYPE.
???????????? 檢查頭部的HEAD_TYPE域 【譯者注:此域指定塊類型】
??? ?if?HEAD_TYPE==0x74????????????? 如果HEAD_TYPE域的值是0x74 【譯者注:表明是文件塊】
???????? read?file?header?(?first?7?bytes?already?read?)
????????????? ? ?讀取文件塊(前 7 個字節已經讀過)
????? ?? read?or?skip?HEAD_SIZE-sizeof(FILE_HEAD)?bytes
??????????????? 讀取或者跳過HEAD_SIZE(?即sizeof(MAIN_HEAD)?)個字節的內容
??????? ?if?(HEAD_FLAGS?&?0x100)??????????????? 如果塊標志的第四位被置為 1 (即 HEAD_FLAGS?&?0x0100?!=0)? 【譯者注:說明HIGH_PACK_SIZE這個頭域存在】
?????????????read?or?skip?HIGH_PACK_SIZE*0x100000000+PACK_SIZE?bytes
????????? ?????? ? 讀取或者跳過已壓縮文件大?。碒IGH_PACK_SIZE*0x100000000+PACK_SIZE)的字節???????????????? 【譯者注:HIGH_PACK_SIZE是文件塊頭部的可選域,是已壓縮文件大小 64 位值的高 4 字節,僅當文件較大時存在。 】
??????? ?else
???????????? ?read?or?skip?PACK_SIZE?bytes
?????????? ??????? 讀取或者跳過已壓縮文件大小(即PACK_SIZE)的字節
???else
????? ?read?corresponding?HEAD_TYPE?block:
???????????? ?讀取HEAD_TYPE所指定類型的塊的內容;
???????read?HEAD_SIZE-7?bytes?????????????? 讀取HEAD_SIZE-7個字節的內容 【譯者注:即塊數據部分】
???????if?(HEAD_FLAGS?&?0x8000)????????????? 如果( HEAD_FLAGS?&?0x8000)?!=?0 【譯者注:即塊標志的首位被置 1 ,亦即說明添加塊存在】
????????? ?read?ADD_SIZE?bytes???????????????? ?讀取ADD_SIZE個字節 【譯者注:即添加塊的內容】
6.?go?to?4.
????
轉到第
4
步
?
???=======================================================================================================
Block?Formats
(常見)塊格式
???=======================================================================================================
???Marker?block?(?MARK_HEAD?)
??????
??標志塊
HEAD_CRC?????? ?2?bytes????? ?Always?0x6152
HEAD_TYPE?????? 1?byte?????????Header?type:?0x72
HEAD_FLAGS? ??2?bytes???????Always?0x1a21
HEAD_SIZE??????? 2?bytes???????Block?size?=?0x0007
???The?marker?block?is?actually?considered?as?a?fixed?byte?sequence:?0x52?0x61?0x72?0x21?0x1a?0x07?0x00
?????????
標志塊事實上被認為是一個固定地字節序列:0x52?0x61?0x72?0x21?0x1a?0x07?0x00
????
???Archive?header?(?MAIN_HEAD?)
????????
歸檔頭部塊
HEAD_CRC???????? 2?bytes????? CRC?of?fields?HEAD_TYPE?to?RESERVED2
??????????????????????????????????????????????????
從頭域HEAD_TYPE到頭域RESERVED2的CRC
HEAD_TYPE??????? 1?byte?????????Header?type:?0x73
HEAD_FLAGS????? 2?bytes???? ?Bit?flags:
????????????????0x0001??-?Volume?attribute?(archive?volume)
???????????????【最低位】??????
卷屬性
標志(歸檔文件卷)
????????????????0x0002??-?Archive?comment?present
???????????????【低二位】?????
?注釋標志
。【此位若被置
1
,注釋存在
】
??????????????????????????RAR?3.x?uses?the?separate?comment?block?and?does?not?set?this?flag.
???????????????????????????
?RAR?3系列的版本使用獨立的注釋塊(來描述歸檔內容),這個標志沒有設定
????????????????0x0004??-?Archive?lock?attribute
???????????????【低三位】???????
歸檔鎖屬性
標志
????????????????0x0008??-?Solid?attribute?(solid?archive)
???????????????【低四位】???????
“
固
實”
屬性
標志
【譯者注:此位若被置
1
,則使用了固實模式壓縮】
????????????????0x0010??-?New?volume?naming?scheme?('volname.partN.rar')
???????????????【低五位】???????
新卷命名方案
存在標志
【譯者注:可否理解為,多卷壓縮的時候,其他卷里的文件命名方案】
????????????????0x0020??-?Authenticity?information?present
?????????????? 【低六位】????????
授權信息
存在標志
?!咀g者注:此位若被置
1
,
授權信息存在】
??????????????????????????RAR?3.x?does?not?set?this?flag.
????????????????????????????
RAR?3系列的版本沒有設定這個標志
????????????????0x0040??-?Recovery?record?present
???????????????【低七位】???????
回復記錄存在標志
?!咀g者注:此位若被置
1
,則
恢復記錄存在】
????????????????0x0080??-?Block?headers?are?encrypted
???????????????【低八位】???????
塊頭加密標志
?!咀g者注:此位若被置
1
,則
塊頭是被加密的】
????????????????0x0100??-?First?volume?(set?only?by?RAR?3.0?and?later)
???????????????【高八位】??????
?首卷標志(只有
RAR3.0
以后的版本
會設置此位
)【譯者注:此位若被置
1
,
則此卷為首卷】
????????????????other?bits?in?HEAD_FLAGS?are?reserved?for?internal?use
????????????????????
其他的位為內部使用保留
HEAD_SIZE???????? ?2?bytes????? ?Archive?header?total?size?including?archive?comments
???????????????????????????????????????????????????
?歸檔頭部塊大小,包括歸檔文件注釋
?!咀g者注:不知此處的注釋是否指歸檔頭部塊的注釋塊】
RESERVED1????? ??2?bytes?????? Reserved
????????????????????????????????????????????????????
保留域
RESERVED2??????? 4?bytes?????? Reserved
????????????????????????????????????????????????????
保留域
???File?header?(File?in?archive)
?
????? ?文件塊(被歸檔的文件)
HEAD_CRC????????????????2?bytes???????CRC?of?fields?from?HEAD_TYPE?to?FILEATTR?and?file?name
????????????????????????????????????????????????????
從頭域HEAD_TYPE到頭域FILEATTR的CRC?????????
HEAD_TYPE???????????????1?byte????????? Header?type:?0x74
HEAD_FLAGS??????????? 2?bytes?????? Bit?flags:
????????????????0x01?-?file?continued?from?previous?volume
???????????????????????????
前文存在標志
?!咀g者注:此位若被置
1
,則
文件從前一個卷繼續】
????????????????0x02?-?file?continued?in?next?volume
???????????????????????????
后文存在標志
。【譯者注:此位若被置
1
,則
文件在后一個卷繼續】
????????????????0x04?-?file?encrypted?with?password
???????????????????????????
加密標志
?!咀g者注:此位若被置
1
,則
文件使用了基于密鑰的加密】
????????????????0x08?-?file?comment?present
???????????????????????????
注釋存在標志
?!咀g者注:此位若被置
1
,則
文件注釋存在】
???????????????????????RAR?3.x?uses?the?separate?comment?block?and?does?not?set?this?flag.
?????????????????????????
RAR?3系列的版本使用獨立的注釋塊(來描述歸檔內容),這個標志沒有設定
????????????????0x10?-?information?from?previous?files?is?used?(solid?flag)?(for?RAR?2.0?and?later)
???????????????????????????
固實標志。此位若被置
1
,則
之前的文件信息被使用(
RAR2.0
及其以后的版本可用)
????????????????bits?7?6?5?(for?RAR?2.0?and?later)【譯者注:原文應該是從
0
開始計數,故此是
0x20、0x40
、
0x80
】
???????????????????????????
第5
、
6
、
7
位表示的是字典的大?。?
RAR2.0及其以后的版本可用)
【譯者注:按照譯者前文的計數習慣,應該是
6
、
7
、
8
位】
?????????????????????0?0?0????-?dictionary?size???64?KB
?????????????????????0?0?1????-?dictionary?size??128?KB
?????????????????????0?1?0????-?dictionary?size??256?KB
?????????????????????0?1?1????-?dictionary?size??512?KB
?????????????????????1?0?0????-?dictionary?size?1024?KB
?????????????????????1?0?1????-?dictionary?size?2048?KB
?????????????????????1?1?0????-?dictionary?size?4096?KB
?????????????????????1?1?1????-?file?is?directory?【譯者注:以整個文件作為字典】
???????????????0x100?-?HIGH_PACK_SIZE?and?HIGH_UNP_SIZE?fields?are?present.?
???????????????????????????? ?
大文件標志
?!咀g者注:此位若被置
1
,則
頭域HIGH_PACK_SIZE?和?HIGH_UNP_SIZE存在。】
???????????????????????These?fields?are?used?to?archiveonly?very?large?files?(larger?than?2Gb),?for?smaller?files?these?fields?are?absent.
?????????????????????????
這些頭域僅用于歸檔很大(大于
2GB
)文件的時候,對于不足2GB的小文件,這些頭域是不存在的。
???????????????0x200?-?FILE_NAME?contains?both?usual?and?encoded?Unicode?name?separated?by?zero.?
????????????????????????????
?此位若被置
1
,則
FILE_NAME同時包括了通常的文件名和用0
隔開的以
Unicode編碼的文件名
????????????????????????In?this?case?NAME_SIZE?field?is?equal?to?the?length?of?usual?name?plus?encoded?Unicode?name?plus?1.
?????????????????????????
在這種情況下,NAME_SIZE?頭域的值就該等于:通常的文件名長度+以Unicode編碼的文件名長度+
1
。
???????????????0x400?-?the?header?contains?additional?8?bytes?after?the?file?name,?which?are?required?to?increase?encryption?security?(so?called?'salt').
???????????????????????????
?強安全性標志。此位若被置
1
,則
頭部在文件名之后還會再附加8
個字節
用來增強加密強度(這被稱之為“鹽”
【譯者注:一個密碼學概念,可理解為干擾因子】)
???????????????0x800?-?Version?flag.?It?is?an?old?file?version,?a?version?number?is?appended?to?file?name?as?';n'.
????????????????????????????? ?
版本標志。此位若被置
1
,則
這是一個老版本的文件,版本號以”;n”的形式被附加到文件名后。
??????????????0x1000?-?Extended?time?field?present.
??????????????????????????????
擴展時間頭域存在標志
?!咀g者注:此位若被置
1
,則
存在擴展的時間頭域】
??????????????0x8000?-?this?bit?always?is?set,?so?the?complete?block?size?is?HEAD_SIZE?+?PACK_SIZE(and?plus?HIGH_PACK_SIZE,?if?bit?0x100?is?set)
??????????????????????????????
數據長度頭域存在標志
。【譯者注:此位若被置
1
,則
頭域PACK_SIZE存在】
此位通常都會被置為1,因此完整的塊大小是HEAD_SIZE?+?PACK_SIZE(
如果
位0x100被設定的話,那么還要加上HIGH_PACK_SIZE)
HEAD_SIZE???????????????2?bytes??? ?File?header?full?size?including?file?name?and?comments
???????????????????????????????????????????
???????????文件塊大小,包括文件名和內容
PACK_SIZE?????????????? 4?bytes?????Compressed?file?size
?????????????????????????????????????????????????????
壓縮后的文件大小
【譯者注:亦即前文所說的數據長度頭域】
UNP_SIZE???????????????? 4?bytes??? ?Uncompressed?file?size
???????????????????????????????????????????????????? ?
沒有壓縮之前的文件大小
HOST_OS????????????????? 1?byte?????? Operating?system?used?for?archiving
?????????????????????????????????????????????????????
歸檔(壓縮)操作時所在的操作系統
??????????????????0?-?MS?DOS
????????????????????1?-?OS/2
????????????????????2?-?Win32
????????????????????3?-?Unix
????????????????????4?-?Mac?OS
????????????????????5?-?BeOS
FILE_CRC???????????????? ?4?bytes????File?CRC
?????????????????????????????????????????????????????
被歸檔文件的CRC
【譯者注:不知是壓縮前還是壓縮后】
FTIME????????????????????????? 4?bytes????Date?and?time?in?standard?MS?DOS?format
??????????????????????????????????????????? ?????????
標準MS?DOS格式的時間和日期
UNP_VER???????? ???????? 1?byte???? ?RAR?version?needed?to?extract?file
???????????????????????????????????????????????????? ?
釋放(即解壓)文件所需要的
RAR
(最低)版本
????????????????Version?number?is?encoded?as?10?*?Major?version?+?minor?version.
????????????????? ?
版本號的是編碼方式是:10*主版本號+小版本號
METHOD????????????????????1?byte?????? Packing?method
?????????????????????????????????????????????????????
打包方式
【譯者注:可理解為壓縮模式】
????????????????0x30?-?storing???????????????????????????? ? 存儲
????????????????0x31?-?fastest?compression????? 最快壓縮
????????????????0x32?-?fast?compression?????????? ?
快壓縮
????????????????0x33?-?normal?compression?????
普通壓縮
????????????????0x34?-?good?compression??????? ?
好壓縮
????????????????0x35?-?best?compression?????????
最好壓縮
NAME_SIZE????????????????2?bytes?? ? File?name?size
?????????????????????????????????????????????????????
?文件名長度
ATTR????????????????????????????4?bytes?????File?attributes
??????????????????????????????????????????????????????
文件屬性
HIGH_PACK_SIZE??? 4?bytes?????High?4?bytes?of?64?bit?value?of?compressed?file?size.
????????????????????????????????????????????????????? ?
已壓縮文件大小的
64
位值的高位四字節
??????????????????????????????????????????????????? Optional?value,?presents?only?if?bit?0x100?in?HEAD_FLAGS?is?set.
??????????????????????????????????????????????????????
可選的頭域,僅當塊標志的0x100位被置為1
時才存在
。
HIGH_UNP_SIZE??????4?bytes???? High?4?bytes?of?64?bit?value?of?uncompressed?file?size.
???????????????????????????????????????????????????????
未壓縮文件大小的
64
位值的高位四字節
????????????????????????????????????????????????????Optional?value,?presents?only?if?bit?0x100?in?HEAD_FLAGS?is?set.
??????????????????????????????????????????????????????
可選的頭域,僅當塊標志的0x100位被置為1
時才存在
。
FILE_NAME????????NAME_SIZE???? File?name?-?string?of?NAME_SIZE?bytes?size
???????????????????????????????????????????????????????
文件名(所占字節數由頭域NAME_SIZE指定)
SALT??????????????????????????8?bytes????? present?if?(HEAD_FLAGS?&?0x400)?!=?0
??????????????????????????????????????????????????????
?鹽。僅當塊標志的0x100位被置為1
時才存在
EXT_TIME??????? ??variable?size???? ?present?if?(HEAD_FLAGS?&?0x1000)?!=?0
??????????????????????????? ??
大小可變????????? ?擴展的時間頭域。僅當塊標志的0x1000位被置為1
時才存在。
other?new?fields?may?appear?here.
??
其他新加的頭域可能在這里出現
?
======================================================================================================
Application?notes
應用注意事項
?======================================================================================================
???1.?To?process?an?SFX?archive?you?need?to?skip?the?SFX?module?searching?for?the?marker?block?in?the?archive.?
????? ??? 處理一個自解壓縮文件的時候,你需要忽略 SFX 模塊對于標志塊的檢查 。
????? There?is?no?marker?block?sequence?(0x52?0x61?0x72?0x21?0x1a?0x07?0x00)?in?the?SFX?module?itself.
???????
?? 在自解壓模塊自身不存在標志塊序列(0x52?0x61?0x72?0x21?0x1a?0x07?0x00)?
???2.?The?CRC?is?calculated?using?the?standard?polynomial?0xEDB88320.?
????? ?? CRC的值由標準的多項式0XEDB88320計算得出。
?????? In?case?the?size?of?the?CRC?is?less?than?4?bytes,?only?the?low?order?bytes?are?used.
????????
在?
CRC
的長度被要求少于
4
字節
的情況下,只使用低
4
字節
。
?
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
