博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有效的数据处理:使用Tango库进行压缩和加密
阅读量:3522 次
发布时间:2019-05-20

本文共 5652 字,大约阅读时间需要 18 分钟。

目录


用于内存中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_AllLZMA_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 processorTang tang2 = new Tang(CompressionAlgo.LZMA8); // use LZMA on 8 processors

加密

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

使用压缩加密

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

在操作中

Tang tang1 = new Tang(CompressionAlgo.GZip1);byte[] plain = ...byte[] compressed = tang1.Zip(plain);byte[] uncompressed = tang1.Unzip(compressed);Tang tang2 = 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 = 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(int 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个字节 

初始化速度

Tang tang = new Tang (CompressionAlgo.LZMA8, "key", "salt", "distr");

Tang构造时间大约需要0.08 ms,与应用的压缩算法无关。 

让您轻松与Tango纠缠在一起!

 

原文地址:

转载地址:http://cuzhj.baihongyu.com/

你可能感兴趣的文章
小甲鱼Python第十八讲(函数:灵活即强大)
查看>>
小甲鱼Python第十九讲(函数,我的地盘听我的)
查看>>
小甲鱼python第二十讲(内嵌函数和闭包)
查看>>
小甲鱼Python第二十一讲(lambda表达式)
查看>>
小甲鱼Python第二十二讲(递归)
查看>>
小甲鱼Python第二十三讲、第二十四讲(递归-这帮小兔崽子、汉诺塔)
查看>>
小甲鱼Python第二十五讲、第二十六讲(字典)
查看>>
小甲鱼Python第二十七讲(集合)
查看>>
2020光学期刊一区二区影响因子发布(科睿唯安)
查看>>
可调谐半导体激光器的窄线宽测试及压缩
查看>>
matlab中 %d,%f,%c,%s
查看>>
常见的光纤接头汇总
查看>>
半导体激光器—问题整理(二)
查看>>
科研日记7.31
查看>>
问题整理3
查看>>
zemax仿真二向色镜
查看>>
stm32单片机编程时extern的用法
查看>>
UART4和5的问题
查看>>
Spring框架中在并发访问时的线程安全性
查看>>
网站部署
查看>>