密码学库Cryptopp不仅给提供了丰富的密码学算法,而且还包含了一些有用的工具类算法,比如本次要讲到的Timer,使用该类定义的对象,可以在程序中统计某一段代码的运行时间。前面我们在讲解随机数发生器的使用的时候,在程序中用到统计产生1G bits的随机数需要的时间。那时,我们使用的C语言库函数clock()。
CryptoPP的LC_RNG算法的使用:
https://blog.csdn.net/Lunar_Queen/article/details/81542372。
源代码如下:
#include<cryptlib.h>
#include<rng.h>//包含LC_RNG算法的头文件
#include<iostream>
#include<fstream>
#include<stdlib.h>
using namespace std;
using namespace CryptoPP;
#define Array_Size 64
int main()
{
//定义一个LCG(线性同余发生器)对象,同时给该RNG赋予种子。
LC_RNG rng(123456);
//定义一个文件对象
ofstream file("data.dat",ios_base::binary | ios_base::out);
byte output[Array_Size];
//产生1Gbits的数据。每调用一次随机数发生器,产生8*64=512bits的数据。
//1Gbits = 1000*1000*1000。
//1000*1000*1000/512 = 1953125。
cout << "开始生成数据..." << endl;
clock_t start = clock();
for(int i=0; i < 1953125 ; ++i)
{
rng.GenerateBlock(output,Array_Size);
file.write(reinterpret_cast<const char*>(output),Array_Size);
}
clock_t end = clock();
cout << "数据生成完毕..." << endl;
double duration;
duration = (double)(end - start) / CLOCKS_PER_SEC;
cout << "生成数据总共耗时:" << duration << endl;
file.close();
return 0;
}
可以看到,上面的代码在加入“统计时间”的代码片段后,显得凌乱。
此时,我们就可以使用Cryptopp提供的Timer算法,不仅很好地完成了时间统计,代码又显得简单整洁。
从上图可以看到Timer提供了几个成员函数,从成员函数的名字就可以很好地知道其作用了。
1、定义Timer类对象tm。
2、在开始计时的地方,调用其成员函数StartTimer () 开始计时。
3、在计时结束的地方,调用其成员函数ElapsedTimeAsDouble ()或ElapsedTime ()或GetCurrentTimerValue 。即可得到程序中某段代码的运行时间。注意,上面几个函数的返回值不一样,其意义也不一样,具体参见其源代码注释。
示例代码如下:
#include<cryptlib.h>
#include<rng.h>//包含LC_RNG算法的头文件
#include<hrtimer.h>
#include<iostream>
#include<fstream>
#include<stdlib.h>
using namespace std;
using namespace CryptoPP;
#define Array_Size 64
int main()
{
//定义一个LCG(线性同余发生器)对象,同时给该RNG赋予种子。
LC_RNG rng(123456);
//定义一个文件对象
ofstream file("data.dat",ios_base::binary | ios_base::out);
byte output[Array_Size];
//产生1Gbits的数据。每调用一次随机数发生器,产生8*64=512bits的数据。
//1Gbits = 1000*1000*1000。
//1000*1000*1000/512 = 1953125。
Timer tm;
cout << "开始生成数据..." << endl;
//clock_t start = clock();
tm.StartTimer();//开始计时
for(int i=0; i < 1953125 ; ++i)
{
rng.GenerateBlock(output,Array_Size);
file.write(reinterpret_cast<const char*>(output),Array_Size);
}
//clock_t end = clock();
cout << "数据生成完毕..." << endl;
//double duration;
//duration = (double)(end - start) / CLOCKS_PER_SEC;
//cout << "生成数据总共耗时:" << duration << endl;
cout << "生成数据总共耗时:" << tm.ElapsedTimeAsDouble() << endl;
file.close();
return 0;
}
从上面的代码可以看出来,替换掉原来统计时间的代码即可。
去掉原来的代码,最终示例代码如下:
#include<cryptlib.h>
#include<rng.h>//包含LC_RNG算法的头文件
#include<hrtimer.h>
#include<iostream>
#include<fstream>
#include<stdlib.h>
using namespace std;
using namespace CryptoPP;
#define Array_Size 64
int main()
{
//定义一个LCG(线性同余发生器)对象,同时给该RNG赋予种子。
LC_RNG rng(123456);
//定义一个文件对象
ofstream file("data.dat",ios_base::binary | ios_base::out);
byte output[Array_Size];
//产生1Gbits的数据。每调用一次随机数发生器,产生8*64=512bits的数据。
//1Gbits = 1000*1000*1000。
//1000*1000*1000/512 = 1953125。
Timer tm;
cout << "开始生成数据..." << endl;
tm.StartTimer();//开始计时
for(int i=0; i < 1953125 ; ++i)
{
rng.GenerateBlock(output,Array_Size);
file.write(reinterpret_cast<const char*>(output),Array_Size);
}
cout << "数据生成完毕..." << endl;
cout << "生成数据总共耗时:" << tm.ElapsedTimeAsDouble() << endl;
file.close();
return 0;
}
执行上述代码,运行结果如下图所示;
由此,可以看到使用程序库不仅让我们减少了工作量和出错的可能性,而且让自己的代码看起来更加简洁明了。
后面,可以看到当使用Cryptopp提供的pipeling范式进行数据处理、传递时,程序会变得更简洁,更加清晰易懂。
更多示例代码详见《深入浅出CryptoPP密码学库》随书电子文档:https://github.com/locomotive-crypto/crypto_book_1st