1. 程式人生 > >有效的資料處理:使用Tango庫進行壓縮和加密

有效的資料處理:使用Tango庫進行壓縮和加密

目錄

介紹

壓縮

加密

Tango庫

壓縮

加密

使用壓縮加密

在操作中

生成

測量


用於記憶體中gziplzma壓縮的.NET庫與基於強blakeb的流密碼引擎結合使用。

介紹

該專案為記憶體資料(如byte陣列和MemoryStream)壓縮和加密引入了一個自持的.NET庫(dll)。當然,處理後的輸出可以儲存到硬碟中,但專案集中在有效的記憶體資料處理方方法上。

壓縮

壓縮的明顯選擇是內建的.NET GZip功能和7Zip SDK C#實現提供的LZM演算法,這是迄今為止最有效的壓縮功能。

由於專案的目的是直接記憶體轉換,因此它不提供具有特定頭結構的7Zip檔案。該庫呼叫GZipLZM壓縮演算法,使用並行程式設計來縮小/擴充記憶體資料,以利用多個CPU核心。

庫可用的壓縮選項來自以下內容

public enum CompressionAlgo {
    GZip_All,
    GZip1,
    GZip2,
    GZip4,
    GZip8,
    LZMA_All,
    LZMA1,
    LZMA2,
    LZMA4,
    LZMA8,
    None
}

其中1,2,4,8代表壓縮期間要處理的處理器數量,Gzip_All

LZMA_All代表所有可用的機器處理器(通常等於8,因此LZMA_AllLZMA8具有相同的含義)。

提供的功能的主要和唯一的目的是記憶體操作。因此儲存到硬碟的單執行緒LZMA1壓縮結果(位元組陣列)形成了可以使用7zip應用程式開啟的正確7z檔案,但多執行緒選項不能提供格式良好的7z檔案。

加密

對於加密部分,該庫引入了基於BlakeB壓縮功能的快速流密碼,由Samuel NevesChristian WinnerleinUli Riehm實現。

BlakeB壓縮功能在生成器的核心工作,該生成器在輸入的鍵、鹽(salt)和分佈值中建立使用者獨有的輸出位元組陣列(pad

)。

生成的pad以下列方式用於加密/解密:

加密:純文字(位元組陣列pXOR pad =>密文(位元組陣列x

解密:密文(xXOR pad =>純文字(p

由於加密和解密功能都只是使用pad對位元組進行異或,因此密碼引擎包括覆蓋這兩種情況的單個函式Crypt,併為我們提供了流密碼實現。

發生器(程式中的BGen類)和流密碼(程式中的Streamer類)都使用多核處理器以並行模式工作。

例如,如果機器有8個處理器,則生成器將生成8個並行陣列並將它們粘合到單個輸出(pad)中。不用說,這些陣列保證是獨一無二的,不會重複。

類似地,Streamer將輸入流分成8個部分,與填充的8個相應部分進行異或,併產生彙總結果。 

讓我們對BlakeB功能進行一些修改。

核心壓縮功能由這些塊組成        

v0 = v0 + v4 + m0;
         v12 = v12 ^ v0;
         v12 = ((v12 >> 32) | (v12 << (32)));
         v8 = v8 + v12;
         v4 = v4 ^ v8;
         v4 = ((v4 >> 24) | (v4 << (40)));
         v0 = v0 + v4 + m1;
         v12 = v12 ^ v0;
         v12 = ((v12 >> 16) | (v12 << (48)));
         v8 = v8 + v12;
         v4 = v4 ^ v8;
         v4 = ((v4 >> 63) | (v4 << (1)));

         v1 = v1 + v5 + m2;
         v13 = v13 ^ v1;
         v13 = ((v13 >> 32) | (v13 << (32)));
         v9 = v9 + v13;
         v5 = v5 ^ v9;
         v5 = ((v5 >> 24) | (v5 << (40)));
         v1 = v1 + v5 + m3;
         v13 = v13 ^ v1;
         v13 = ((v13 >> 16) | (v13 << (48)));
         v9 = v9 + v13;
         v5 = v5 ^ v9;
         v5 = ((v5 >> 63) | (v5 << (1))); 
...

具有重複的移位常數32,24,1663.每個常數在12輪處理中出現96次,總共384次。

為了使對手的生活更有趣,當前的實現最初基於使用者密碼(金鑰),鹽(salt)和分佈輸入生成位元組陣列S [384]。這允許在壓縮函式中有以下模式:

        

 int i = 0;

         v0 = v0 + v4 + m0;
         v12 = v12 ^ v0;
         v12 = RR(v12, S[i++]);
         v8 = v8 + v12;
         v4 = v4 ^ v8;
         v4 = RR(v4, S[i++]);
         v0 = v0 + v4 + m1;
         v12 = v12 ^ v0;
         v12 = RR(v12, S[i++]);
         v8 = v8 + v12;
         v4 = v4 ^ v8;
         v4 = RR(v4, S[i++]); 
...

其中RR是右移函式

private ulong RR(ulong x, byte n) {

     return (x >> n) | (x << (-n & 63));
}

因此,壓縮函式利用取決於使用者輸入的金鑰,鹽(salt)和分佈的唯一組384個移位數(位元組),從而消除來自計算的任意常數。 

生成器中唯一的常量是程式設計師定義的ulongs

private const ulong IV0 =  9111111111111111111;
private const ulong IV1 =  8222222222222222222;
private const ulong IV2 =  7333333333333333333;
private const ulong IV3 =  6444444444444444444;
private const ulong IV4 =  5555555555555555555;
private const ulong IV5 =  4666666666666666666;
private const ulong IV6 =  3777777777777777777;
private const ulong IV7 =  2888888888888888888;
private const ulong IV8 =  1999999999999999999;
private const ulong IV9 =  1111111111111111111;
private const ulong IV10 = 2222222222222222222;
private const ulong IV11 = 3333333333333333333;
private const ulong IV12 = 4444444444444444444;
private const ulong IV13 = 5555555555555555555;
private const ulong IV14 = 6666666666666666666;
private const ulong IV15 = 7777777777777777777;

private const ulong FNL0 = 123456789;
private const ulong FNL1 = 987654321;

在您的實現中設定唯一常量,並享受可靠靈活的個人流密碼,其中沒有任何外部預定義。

使用者提供的鹽(salt)和分佈輸入會影響生成器的初始狀態,因此會增加結果的分散。 

Tango

Tango庫的Tang類是一個單一的入口點,具有僅用於壓縮、僅用於加密或同時用於兩者的介面。

這是建構函式用法示例。

壓縮

Tang tang1 = new Tang(CompressionAlgo.GZip1); // use GZip on 1 processor

Tang tang2 = new Tang(CompressionAlgo.LZMA8); // use LZMA on 8 processors

加密

Tang<code> </code>tang3 = new Tang("key", "salt", "distr", 1); // use 1 processor for encryption

Tang tang4 = new Tang(key, salt, distr); // use all processors for encryption. key,salt and distr are byte arrays

使用壓縮加密

Tang tang5<code> </code>= new Tang(CompressionAlgo.GZip8, "key", "salt", "distr", 4); // GZip8 compression, 4 processors for encryption

Tang tang6 = new Tang(CompressionAlgo.LZMA1, "key", "salt", "distr"); // LZMA1 compression, all processors for encryption

在操作中

Tang tang1<code> </code>= new Tang(CompressionAlgo.GZip1);

byte[] plain = ...

byte[] compressed = tang1.Zip(plain);
byte[] uncompressed = tang1.Unzip(compressed);


Tang tang<code>2 </code>= new Tang("key", "salt", "distr");

byte[] encrypted= tang2.Crypt(plain);

// The reset is needed when using the same tang object for the paired encrypt/decrypt and tangle/untangle actions.

tang2.Reset();

byte[] decrypted = tang2.Crypt (encrypted);


Tang tang3<code> </code>= new Tang(CompressionAlgo.LZMA1, "key", "salt", "distr");

byte[] tangled = tang3.Tangle(plain); // Tangle is Crypt(Zip(plain))

tang3.Reset();

byte[] untangled = tang3.Untangle(tangled); // Untangle is Unzip(Crypt(tangled))

還有Tango函式使用MemoryStream輸入引數,而不是位元組陣列作為引數。

不要忘記在un-unzipUntangle操作中放置try / catch塊。

生成

初始化後,tang物件可以生成給定長度的位元組陣列,該位元組陣列對於提供的金鑰,鹽(salt)和分佈是唯一的:

Tang tang = new Tang("key", "salt", "distr");
byte[] hash = tang.Generate(<code>int </code>length);

測量

PCi7 2GHz 648

Tangle()

Source    9,653,618 B (fb2 file - allows for high compression)

                                              time               compression rate

GZip1       2,463,446 B           1259 ms          25.52% 

GZip8       2,472,430 B             303 ms          25.61%

LZMA1    1,777,219 B          30995 ms          18.41% 

LZMA8     1,914,649 B          6124 ms           19.83%

僅限壓縮

Source  9653618 B                                        timing              compression rate

GZip1     2,463,446 B          1169 ms                3.7%                 25.52%

GZip8     2,472,430 B            293 ms                0.9%                 25.61%

LZMA1   1,777,219 B        31377 ms            100%                    18.41%

LZMA8   1,914,649 B          6131 ms              19.5%                 19.83%

預期最有效的壓縮演算法是LZMA1,它具有最高的時間成本。

GZip8GZip14倍,壓縮效果幾乎不差。

僅限加密

Source   9653618 B

              time               

1 core    903 ms    100%

2 cores  457 ms       50.6%

4 cores  295 ms       32.7%             

8 cores  219 ms       24.3%                  

生成

250毫秒內生成10,000,000個位元組 

初始化速度

<code>Tang tang </code>= new <code>Tang </code>(CompressionAlgo.LZMA8, "key", "salt", "distr");

Tang構造時間大約需要0.08 ms,與應用的壓縮演算法無關。 

讓您輕鬆與Tango糾纏在一起!

 

原文地址:https://www.codeproject.com/Articles/1273094/Effective-data-handling-compress-and-encrypt-with