1、算法概述

  数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名、数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密。数据摘要算法也被称为哈希(Hash)算法或散列算法。

  1.1、CRC8、CRC16、CRC32

  CRC(Cyclic Redundancy Check,循环冗余校验)算法出现时间较长,应用也十分广泛,尤其是通讯领域,现在应用最多的就是 CRC32 算法,它产生一个4字节(32位)的校验值,一般是以8位十六进制数,如FA 12 CD 45等。CRC算法的优点在于简便、速度快,严格的来说,CRC更应该被称为数据校验算法,但其功能与数据摘要算法类似,因此也作为测试的可选算法。
在 WinRAR、WinZIP 等软件中,也是以 CRC32 作为文件校验算法的。一般常见的简单文件校验(Simple File Verify – SFV)也是以 CRC32算法为基础,它通过生成一个后缀名为 .SFV 的文本文件,这样可以任何时候可以将文件内容 CRC32运算的结果与 .SFV 文件中的值对比来确定此文件的完整性。
与 SFV 相关工具软件有很多,如MagicSFV、MooSFV等。
  1.2、MD2 、MD4、MD5
  这是应用非常广泛的一个算法家族,尤其是 MD5(Message-Digest Algorithm 5,消息摘要算法版本5),它由MD2、MD3、MD4发展而来,由Ron Rivest(RSA公司)在1992年提出,被广泛应用于数据完整性校验、数据(消息)摘要、数据加密等。MD2、MD4、MD5 都产生16字节(128位)的校验值,一般用32位十六进制数表示。MD2的算法较慢但相对安全,MD4速度很快,但安全性下降,MD5比MD4更安全、速度更快。
在互联网上进行大文件传输时,都要得用MD5算法产生一个与文件匹配的、存储MD5值的文本文件(后缀名为 .md5或.md5sum),这样接收者在接收到文件后,就可以利用与 SFV 类似的方法来检查文件完整性,绝大多数大型软件公司或开源组织都是以这种方式来校验数据完整性,而且部分操作系统也使用此算法来对用户密码进行加密,另外,它也是目前计算机犯罪中数据取证的最常用算法。
与MD5 相关的工具有很多,如 WinMD5等。
  1.3、SHA1、SHA256、SHA384、SHA512
  SHA(Secure Hash Algorithm)是由美国专门制定密码算法的标准机构—— 美国国家标准技术研究院(NIST)制定的,SHA系列算法的摘要长度分别为:SHA为20字节(160位)、SHA256为32字节(256位)、 SHA384为48字节(384位)、SHA512为64字节(512位),由于它产生的数据摘要的长度更长,因此更难以发生碰撞,因此也更为安全,它是未来数据摘要算法的发展方向。由于SHA系列算法的数据摘要长度较长,因此其运算速度与MD5相比,也相对较慢。
SHA1的应用较为广泛,主要应用于CA和数字证书中,另外在互联网中流行的BT软件中,也是使用SHA1来进行文件校验的。
  1.4、RIPEMD、PANAMA、TIGER、ADLER32 等
  RIPEMD是Hans Dobbertin等3人在对MD4,MD5缺陷分析基础上,于1996年提出来的,有4个标准128、160、256和320,其对应输出长度分别为16字节、20字节、32字节和40字节。IGER由Ross在1995年提出。Tiger号称是最快的Hash算法,专门为64位机器做了优化。
  注:来源百度百科:摘要算法
 
  2、算法测试
  基于openssl中提供的MD5、SHA1、SHA256和zlib中提供的CRC32,测试平台:OSX10.12
  check.h
  

#ifndef HEADER_CHECK_H
# define HEADER_CHECK_H #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/md5.h>
#include <openssl/sha.h> #include "zlib.h" #ifdef __cplusplus
extern "C"{
#endif #define BUFSIZE 1024*1024*2 /*
* 使用OpenSSL提供的MD5相关函数计算字符串和大文件的MD5值
*/
int calcBufMD5(unsigned char *src, size_t len,unsigned char *dst);
int calcFileMD5(const char *inFile,unsigned char *dst); /*
* 使用OpenSSL提供的SHA1 SAH256函数分别计算字符串和大文件的SAH1 SAH256值
*/
int calcBufSHA1(unsigned char *src, size_t len,unsigned char *dst);
int calcFileSHA1(const char *inFile,unsigned char *dst); int calcBufSHA256(unsigned char *src, size_t len,unsigned char *dst);
int calcFileSHA256(const char *inFile,unsigned char *dst); /*
* 自实现CRC32校验(查表法)
* 用以计算字符串和大文件的CRC32值
*/
unsigned int calcBufCRC32(unsigned int crc,unsigned char *buf,size_t len);
unsigned int calcFileCRC32(const char *inFile); # ifdef __cplusplus
}
# endif # endif

  check.c

#include "check.h"
#include <stdlib.h> //计算字符串的MD5
int calcBufMD5(unsigned char *src,size_t len,unsigned char *dst)
{
if(NULL == src || NULL == dst)
{
fprintf(stderr,"%s\n","input parameter error");
return -;
} MD5(src,len,dst); return ;
} //计算大文件的MD5值
int calcFileMD5(const char *inFile,unsigned char *dst)
{
if(NULL == inFile || NULL == dst)
{
fprintf(stderr,"%s\n","input parameter error");
return -;
} char buf[BUFSIZE] = {}; int nread;
MD5_CTX ctx;
FILE *fin = fopen(inFile,"r");
if(NULL == fin)
{
fprintf(stderr,"%s\n","open file error");
return -;
} MD5_Init(&ctx);
while((nread = fread(buf,,BUFSIZE,fin)) > )
{
MD5_Update(&ctx,buf,nread);
} MD5_Final(dst,&ctx); return ;
} //计算字符串的SHA1
int calcBufSHA1(unsigned char *src, size_t len,unsigned char *dst)
{
if(NULL == src || NULL == dst)
{
fprintf(stderr,"%s\n","input parameter error");
return -;
} unsigned char sha[] = {};
char tmp[] = {};
int i; SHA1(src,len,dst); for(i = ; i < ; i++)
{
sprintf(tmp,"%02x",sha[i]);
strcat((char*)dst,tmp);
} return ;
}
//计算大文件的SAH1
int calcFileSHA1(const char *inFile,unsigned char *dst)
{
if(NULL == inFile || NULL == dst)
{
fprintf(stderr,"%s\n","input parameter error");
return -;
} char buf[BUFSIZE] = {};
unsigned char sha[] = {};
char tmp[] = {};
int i,nread;
SHA_CTX ctx;
FILE *fin = fopen(inFile,"r");
if(NULL == fin)
{
fprintf(stderr,"%s\n","open file error");
return -;
} SHA1_Init(&ctx);
while((nread = fread(buf,,BUFSIZE,fin)) > )
{
SHA1_Update(&ctx,buf,nread);
}
SHA1_Final(dst,&ctx); fclose(fin);
return ;
} //计算字符串的SAH256
int calcBufSHA256(unsigned char *src, size_t len,unsigned char *dst)
{
if(NULL == src || NULL == dst)
{
fprintf(stderr,"%s\n","input parameter error");
return -;
} unsigned char sha[] = {};
char tmp[] = {};
int i; SHA256(src,len,dst);
return ;
}
//计算大文件的SAH256
int calcFileSHA256(const char *inFile,unsigned char *dst)
{
if(NULL == inFile || NULL == dst)
{
fprintf(stderr,"%s\n","input parameter error");
return -;
} char buf[BUFSIZE] = {};
unsigned char sha[] = {};
char tmp[] = {};
int i,nread;
SHA256_CTX ctx;
FILE *fin = fopen(inFile,"r");
if(NULL == fin)
{
fprintf(stderr,"%s\n","open file error");
return -;
} SHA256_Init(&ctx);
while((nread = fread(buf,,BUFSIZE,fin)) > )
{
SHA256_Update(&ctx,buf,nread);
}
SHA256_Final(dst,&ctx); fclose(fin); return ;
} //计算字符串的CRC32
unsigned int calcBufCRC32(unsigned int crc,unsigned char *buf,size_t len)
{
return crc32(crc,buf,len);
}
//计算大文件的CRC32
unsigned int calcFileCRC32(const char *inFile)
{
int nread;
unsigned char buf[BUFSIZE] = {};
unsigned int crc = ; FILE *fin = fopen(inFile,"rb");
if(NULL == fin)
{
fprintf(stderr,"%s\n","open file error");
return -;
} while((nread = fread(buf,,BUFSIZE,fin)) > )
crc = calcBufCRC32(crc,buf,nread); fclose(fin); return crc;
}

  test.c 

#include <stdio.h>
#include <sys/time.h>
#include "check.h" int main(int argc,char *argv[])
{
unsigned char *data = ""; struct timeval start;
struct timeval end;
double diff; unsigned char *md = (unsigned char *)malloc();
if(NULL == md)
{
fprintf(stderr,"%s\n","malloc error");
return -;
} memset(md,,sizeof(md));
gettimeofday(&start,NULL);
calcFileMD5(argv[],md);
gettimeofday(&end,NULL); diff = (end.tv_sec - start.tv_sec)* + (end.tv_usec - start.tv_usec); printf("%s MD5:%s\n",argv[],md);
for(int i = ; i< ;i++)
printf("%02x",md[i]);
printf("spend time :%fs\n\n",diff/); diff =;
gettimeofday(&start,NULL);
unsigned crc = calcFileCRC32(argv[]);
gettimeofday(&end,NULL); diff = (end.tv_sec - start.tv_sec)* + (end.tv_usec - start.tv_usec); printf("%s CRC32:%u\n",argv[],crc);
printf("spend time :%fs\n\n",diff/); diff = ;
memset(md,,sizeof(md));
gettimeofday(&start,NULL);
calcFileSHA1(argv[],md);
gettimeofday(&end,NULL); diff = (end.tv_sec - start.tv_sec)* + (end.tv_usec - start.tv_usec); printf("%s SHA1:%s\n",argv[],md);
printf("spend time :%fs\n\n",diff/); diff =;
memset(md,,sizeof(md));
gettimeofday(&start,NULL);
calcFileSHA256(argv[],md);
gettimeofday(&end,NULL); diff = (end.tv_sec - start.tv_sec)* + (end.tv_usec - start.tv_usec); printf("%s SHA256:%s\n",argv[],md);
printf("spend time :%fs\n\n",diff/); free(md); return ;
}

  说明:经过MD5、SHA1和SHA256计算出的校验值需要再经过一层转换,才能成为可识别的字符串,以MD5为例:

for(int i = ; i< ;i++)
printf("%02x",md[i]);

添砖加瓦:几种常见的数据摘要算法(MD5、CRC32、SHA1和SHA256)的更多相关文章

  1. Java 常见摘要算法——md5、sha1、sha256

    目录 摘要算法简介 md5 使用jdk内置方法实现md5加密 使用bc方式实现md5加密 使用cc方式实现md5加密 sha1 使用jdk内置方法实现sha1加密 使用bc方式实现sha1加密 使用c ...

  2. App6种常见的数据加载设计

    App6种常见的数据加载设计 设计师在进行APP设计的设计时,往往会更加专注于界面长什么样,界面和界面之间怎么跳转,给予用户什么样的操作反馈,却偏偏特别容易忽略掉一个比较重要的环节,就是APP数据加载 ...

  3. 2.Hive的几种常见的数据导入方式

    好久没写Hive的那些事了,今天开始写点吧.今天的话题是总结Hive的几种常见的数据导入方式,我总结为四种:(1).从本地文件系统中导入数据到Hive表:(2).从HDFS上导入数据到Hive表:(3 ...

  4. MD5,SHA1及SHA256等哈希加密方法实现:Java,C#,Golang,Python

    哈希算法又称散列算法,它可以从任何数据中快速的创建一个凭证,而这个凭证很难被推倒出来,因为一丁点的变化会导致凭证的差别恨到,也就是说哈希算法具有不可逆性,因此它在密码数据校验方面用的很广,比如我们常用 ...

  5. 摘要算法CRC8、CRC16、CRC32,MD2 、MD4、MD5,SHA1、SHA256、SHA384、SHA512,RIPEMD、PANAMA、TIGER、ADLER32

    1.CRC8.CRC16.CRC32 CRC(Cyclic Redundancy Check,循环冗余校验)算法出现时间较长,应用也十分广泛,尤其是通讯领域,现在应用最多的就是 CRC32 算法,它产 ...

  6. Python中摘要算法MD5,SHA1讲解

    摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示).摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要di ...

  7. .net实现md5加密 sha1加密 sha256加密 sha384加密 sha512加密 des加密解密

    写项目时,后台一直用md5加密,一天群里人问,除了MD5还有其它的加密方法吗?当时只知道还有个SHA,但怎么实现什么的都不清楚,于是当网上找了下,把几种常见的加密方法都整理了下,用winform写了个 ...

  8. android端从服务器抓取的几种常见的数据的处理方式

    1.图片 public void look(View v) { String path = et_path.getText().toString(); try { URL url = new URL( ...

  9. win7和linux下利用命令查看文件md5、sha1、sha256

    win7 certutil -hashfile <filename> MD5 certutil -hashfile <filename> SHA1 certutil -hash ...

随机推荐

  1. JAVA--Mybatis-Spring-SpringMVC框架整合

    ------Mybatis-Spring-SpringMVC框架整合示例----- mybatis SQL映射文件 <?xml version="1.0" encoding= ...

  2. ES6 find()

    Array.prototype.find() 返回数组中满足提供测试函数的第一个元素的值,否则返回undefined let b = blogs.find(function(e) => { re ...

  3. 利用 wave 库 对音频进行格式处理

    import wave r = r"D:\沫沫酱 - 旧伤口.wav" # 一个.wav格式文件 with wave.open(r, "rb") as f: # ...

  4. mybatis使用Map<String,Object>映射mysql结果集,关于字段的问题

    --mysql常用字段类型如图 --mybatis使用Map<String,Object>映射,会将tinyint映射成Integer类型.decimal映射成BigDecimal类型 所 ...

  5. E、阔力梯的树

    题:https://ac.nowcoder.com/acm/contest/4010/E?&headNav=acm 分析:dsu.贪心方法:考虑插入一个值x,对总体贡献,若查找在序列中左边有值 ...

  6. jmeter 配置csv 登陆网站 报错

    0 环境 系统环境:win7 1 正文 1 问题 创建csv 格式为utf-8后 jmeter csv配置好后 post请求登陆报错 2 解决 查看了一下报告 post请求里用户名乱码了 仔细一看网站 ...

  7. 【DSP】TMS320F28335的GPIO

    --> 关于TMS320F28335的GPIO的基础操作 TI的c2000系列DSP大多数的外设信号与通用输入/输出 (GPIO) 信号复用. 这使得用户能够在外设信号或者功能不使用时将一个引脚 ...

  8. 吴裕雄--天生自然C语言开发:位域

    struct { unsigned int widthValidated; unsigned int heightValidated; } status; struct { unsigned ; un ...

  9. G - Green-Red Tree Gym - 102190G

    题目链接:http://codeforces.com/gym/102190/attachments 题解:我们先将前5个点分别涂上红色或者绿色,使得这两棵树在5个点中都是连通,并不存在自环(建边方式不 ...

  10. 绿洲作业第一周 - 美术Art work

    Dear parents, Please remind your child to learn and finish the work as follows from the art teacher: ...