溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 服務器 > 
  • gzip壓縮文件底層結構及文件損壞的修復方法是什么

gzip壓縮文件底層結構及文件損壞的修復方法是什么

發(fā)布時間:2022-01-17 14:32:11 來源:億速云 閱讀:342 作者:iii 欄目:服務器

本文小編為大家詳細介紹“gzip壓縮文件底層結構及文件損壞的修復方法是什么”,內容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“gzip壓縮文件底層結構及文件損壞的修復方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

接修復損壞的gzip壓縮文件之原理篇,再次引用GZIP結構圖:
gzip壓縮文件底層結構及文件損壞的修復方法是什么

已知修復一個損壞的gzip文件的關鍵環(huán)節(jié)在于找到下一個正常壓縮包的起始點。根據結構圖中的信息可知,每個壓縮包的開始結構中有是否到達尾部標志、使用的哈夫曼樹類型、以及3個哈夫曼樹的樹元素個數等。如果某個gzip文件中間有一個壞扇區(qū),要找到壞扇區(qū)后的一個正常起點,僅需按位右移,一直移位到可以正常解壓的某個位,就可能找到了正確的壓縮包起始。而根據gzip文件的壓縮作業(yè)窗口為32KB大小推算,這個遍歷不會超過64KB即可找到。在內存中快速循環(huán)可以很快找到,但需要有明確的判斷錯誤的方法。

首先可以明確的是結尾標志,應該為0(我們是從損壞的點向后查)。而哈夫曼樹類型也大致應該是動態(tài)哈夫曼(0x02),cl1的元素個數應該取值為257到286之間(包含邊界),cl2的元素個數應小于等于30,ccl的元素個數取值可為1-15(包含邊界)。
其實,還可以參考的東西有,解開的哈夫曼樹是否異常,或者通過規(guī)律性原則找到最后一個取值為256的值,但這些算法應該是較為麻煩的,有上面的算法連續(xù)校驗幾個壓縮塊就足夠了。

具體方法是對gzip的源碼做修改,進行遍歷。因時間關系,未做成通用工程,僅快速修改了部分代碼。大致的修改點為:

一,找到損壞點:

在unzip.c中,
error("invalid compressed data--format violated");
這一行前,獲取當前解碼字節(jié)位置即可。

二、遍歷找到損壞點:

1、inflate.c文件中,改

if (nl > 286 || nd > 30)
#endif
return 1;


為:

if (nl > 286 || nd > 30||nl <257 || nd <1)
#endif
return 1;


2、inflate.c文件中,在int inflate_block(e)函數中
在如下代碼前

bb = b; 
bk = k;


加入代碼:

if ((t != 2) || (*e != 0)) 
return 2;


3、inflate.c文件中,在int inflate_block(e)函數尾部
把if (t == 0) 與if (t == 1)的情況都直接返回錯誤值2。
 
4、inflate.c文件中,函數int inflate()中,改

if ((r = inflate_block(&e)) != 0) 
return r; 
end


為:

unsigned t;           /* block type */ 
register ulg b;       /* bit buffer */ 
register unsigned k;  /* number of bits in bit buffer */ 
while (inptr <= insize) 
{ 
    unsigned int tptr = inptr; 
    unsigned int tbk = bk; 
    unsigned long tbb = bb; 
    unsigned int twp = wp; 
    long long tstart = *(long long*)(inbuf + tptr); 
    if ((r = inflate_block(&e)) != 0) 
    { 
        inptr = tptr; 
        bb = tbb; 
        bk = tbk; 
        wp = twp; 
        b = bb; 
        k = bk; 
        NEEDBITS(1) 
        DUMPBITS(1) 
    } 
    else 
    { 
        printf("get by www.datahf.net!"); //也可輸出tstart,bb,bk 值,轉載時請保留版權信息:www.datahf.net張宇 
    } 
}


此4步完成后,試著調試這個錯誤的.gz文件,當然,也可以在代碼中解釋完頭部結構后加一個seek,直接seek到損壞位置。
通常情況下,輸出printf(“get by www.datahf.net!”)這行代碼時,已經找到了正確的起始位。
找到起始位后,也可以構造或拷貝一個正常的gzip文件頭,再拼接好找到的位流,即可解壓了。(如果位流不是字節(jié)對齊的,可能要全部做位移)。拼接后很多壓縮文件就可以打開甚至于解壓了,不過,有可能會報錯,主要是尾部的校驗和大小錯,其實可以忽略。
如果拼接好了linux下,不能直接用“gzip –d”解壓,因其crc有錯誤,會導致解壓到99%后報錯,然后把文件刪除,換成管道命令即可。

讀到這里,這篇“gzip壓縮文件底層結構及文件損壞的修復方法是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI