sha1/sha256/md5/crc32这几种算法都是目前比较常用的摘要算法,在我们实际开发中,经常会需要使用,我们该如何选择呢,哪个算法的速度更快呢?
我们选择了一个差不多1G大小的system.img来分别计算下这四种不同的摘要信息,我们写了一个脚本来计算,更方便我们查看对比结果:
date -u +%r
sha256sum system.img
date -u +%r
sha1sum system.img
date -u +%r
md5sum system.img
date -u +%r
cksum system.img
date -u +%r
我们执行下这个脚本,打印如下:
我们计算下时间:
sha256: 5s 64字符
sha1: 3s 40字节
md5: 2s 32字节
crc32: 3s 10字节
从时间上来看: md5 < sha1 = crc32 < sha256
从摘要长度看: crc32 < md5 < sha1 < sha256
这个我们是直接使用现有的工具计算速度,我们代码中如何计算呢,我们以sha1为例,使用C代码计算下system.img摘要信息
#include
#include
#include
#include
#define BUFFER_SIZE (10*1024*1024)
static const char hex_chars[] = "0123456789abcdef";
void convert_hex(unsigned char *md, unsigned char *mdstr) {
int i;
int j = 0;
unsigned int c;
for (i = 0; i < 20; i++) {
c = (md[i] >> 4) & 0x0f;
mdstr[j++] = hex_chars[c];
mdstr[j++] = hex_chars[md[i] & 0x0f];
}
mdstr[40] = '\0';
}
int main(int argc, char **argv) {
int read = 0;
SHA_CTX shactx;
char md[SHA_DIGEST_LENGTH];
char mdstr[40];
SHA1_Init(&shactx);
FILE *p=fopen(argv[1], "r");
if (p==NULL) {
printf("open %s failed!\n", argv[1]);
return -1;
}
unsigned char *buf = (unsigned char *)malloc(BUFFER_SIZE);
if (buf == NULL) {
printf("malloc %d failed!\n", BUFFER_SIZE);
fclose(p);
return -1;
}
while(!feof(p)) {
read = fread(buf, 1, BUFFER_SIZE, p);
SHA1_Update(&shactx, buf, read);
}
free(buf);
buf = NULL;
fclose(p);
SHA1_Final(md, &shactx);
convert_hex(md, mdstr);
printf ("Result of SHA1 : %s\n", mdstr);
return 0;
}
我们直接编译gcc main.c -lcrypto 生成a.out可执行文件:
date -u +%r
./a.out system.img
date -u +%r
执行结果如下:
11:50:22 AM
Result of SHA1 : 2f5c5a4664026c6a9a1f330f6510d7d9efc2910f
11:50:24 AM
差不多2s,就可以计算出sha1值,好像比我们之前使用工具计算的3s还有快一些,我们每次读的缓存是10M,是不是跟这个有关系呢,我们对比下不同的缓存大小的情况:我们把BUFFER_SIZE大小修改为1M与100M再次计算:
1M时:(耗时2s)
11:53:04 AM
Result of SHA1 : 2f5c5a4664026c6a9a1f330f6510d7d9efc2910f
11:53:06 AM
100M时:(耗时2s)
11:53:39 AM
Result of SHA1 : 2f5c5a4664026c6a9a1f330f6510d7d9efc2910f
11:53:41 AM
综上对比,计算sha1值时,跟每次计算的缓存大小关系不大,主要的耗时还是在数据计算过程。