`
re_reference
  • 浏览: 236704 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

C 语言版 SHA1算法

阅读更多


/* 
 
 SHA-1   in   C 
 
 By   Steve   Reid   <steve@edmweb.com> 
 
 100%   Public   Domain 
 
 
 Test   Vectors   (from   FIPS   PUB   180-1) 
 
 "abc " 
 
 A9993E36   4706816A   BA3E2571   7850C26C   9CD0D89D 
 
 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq " 
 
 84983E44   1C3BD26E   BAAE4AA1   F95129E5   E54670F1 
 
 A   million   repetitions   of   "a " 
 
 34AA973C   D4C4DAA4   F61EEB2B   DBAD2731   6534016F 
 
 */ 


/*   #define   LITTLE_ENDIAN   *   This   should   be   #define 'd   if   true.   */ 

/*   #define   SHA1HANDSOFF   *   Copies   data   before   messing   with   it.   */ 


#include   <stdio.h> 
#include   <string.h>

typedef   struct  { 
    
    unsigned   long   state[5]; 
    
    unsigned   long   count[2]; 
    
    unsigned   char   buffer[64]; 
    
}   SHA1_CTX; 


void   SHA1Transform(unsigned   long   state[5],   unsigned   char   buffer[64]); 

void   SHA1Init(SHA1_CTX*   context); 

void   SHA1Update(SHA1_CTX*   context,   unsigned   char*   data,   unsigned   int   len); 

void   SHA1Final(unsigned   char   digest[20],   SHA1_CTX*   context); 


#define   rol(value,   bits)   (((value)   <<   (bits))   |   ((value)   >>   (32   -   (bits)))) 


/*   blk0()   and   blk()   perform   the   initial   expand.   */ 

/*   I   got   the   idea   of   expanding   during   the   round   function   from   SSLeay   */ 

#ifdef   LITTLE_ENDIAN 

#define   blk0(i)   (block-> l[i]   =   (rol(block-> l[i],24)&0xFF00FF00)|(rol(block-> l[i],8)&0x00FF00FF)) 

#else 

#define   blk0(i)   block-> l[i] 

#endif 

#define   blk(i)   (block-> l[i&15]   =   rol(block-> l[(i+13)&15]^block-> l[(i+8)&15]^block-> l[(i+2)&15]^block-> l[i&15],1)) 


/*   (R0+R1),   R2,   R3,   R4   are   the   different   operations   used   in   SHA1   */ 

#define   R0(v,w,x,y,z,i)   z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 

#define   R1(v,w,x,y,z,i)   z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 

#define   R2(v,w,x,y,z,i)   z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 

#define   R3(v,w,x,y,z,i)   z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 

#define   R4(v,w,x,y,z,i)   z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 


/*   Hash   a   single   512-bit   block.   This   is   the   core   of   the   algorithm.   */ 


void   SHA1Transform(unsigned   long   state[5],   unsigned   char   buffer[64]) 

{ 
    
    unsigned   long   a,   b,   c,   d,   e; 
    
    typedef   union   { 
        
        unsigned   char   c[64]; 
        
        unsigned   long   l[16]; 
        
    }   CHAR64LONG16; 
    
    CHAR64LONG16*   block; 
    
#ifdef   SHA1HANDSOFF 
    
    static   unsigned   char   workspace[64]; 
    
    block   =   (CHAR64LONG16*)workspace; 
    
    memcpy(block,   buffer,   64); 
    
#else 
    
    block   =   (CHAR64LONG16*)buffer; 
    
#endif 
    
    /*   Copy   context-> state[]   to   working   vars   */ 
    
    a   =   state[0]; 
    
    b   =   state[1]; 
    
    c   =   state[2]; 
    
    d   =   state[3]; 
    
    e   =   state[4]; 
    
    /*   4   rounds   of   20   operations   each.   Loop   unrolled.   */ 
    
    R0(a,b,c,d,e,   0);   R0(e,a,b,c,d,   1);   R0(d,e,a,b,c,   2);   R0(c,d,e,a,b,   3); 
    
    R0(b,c,d,e,a,   4);   R0(a,b,c,d,e,   5);   R0(e,a,b,c,d,   6);   R0(d,e,a,b,c,   7); 
    
    R0(c,d,e,a,b,   8);   R0(b,c,d,e,a,   9);   R0(a,b,c,d,e,10);   R0(e,a,b,c,d,11); 
    
    R0(d,e,a,b,c,12);   R0(c,d,e,a,b,13);   R0(b,c,d,e,a,14);   R0(a,b,c,d,e,15); 
    
    R1(e,a,b,c,d,16);   R1(d,e,a,b,c,17);   R1(c,d,e,a,b,18);   R1(b,c,d,e,a,19); 
    
    R2(a,b,c,d,e,20);   R2(e,a,b,c,d,21);   R2(d,e,a,b,c,22);   R2(c,d,e,a,b,23); 
    
    R2(b,c,d,e,a,24);   R2(a,b,c,d,e,25);   R2(e,a,b,c,d,26);   R2(d,e,a,b,c,27); 
    
    R2(c,d,e,a,b,28);   R2(b,c,d,e,a,29);   R2(a,b,c,d,e,30);   R2(e,a,b,c,d,31); 
    
    R2(d,e,a,b,c,32);   R2(c,d,e,a,b,33);   R2(b,c,d,e,a,34);   R2(a,b,c,d,e,35); 
    
    R2(e,a,b,c,d,36);   R2(d,e,a,b,c,37);   R2(c,d,e,a,b,38);   R2(b,c,d,e,a,39); 
    
    R3(a,b,c,d,e,40);   R3(e,a,b,c,d,41);   R3(d,e,a,b,c,42);   R3(c,d,e,a,b,43); 
    
    R3(b,c,d,e,a,44);   R3(a,b,c,d,e,45);   R3(e,a,b,c,d,46);   R3(d,e,a,b,c,47); 
    
    R3(c,d,e,a,b,48);   R3(b,c,d,e,a,49);   R3(a,b,c,d,e,50);   R3(e,a,b,c,d,51); 
    
    R3(d,e,a,b,c,52);   R3(c,d,e,a,b,53);   R3(b,c,d,e,a,54);   R3(a,b,c,d,e,55); 
    
    R3(e,a,b,c,d,56);   R3(d,e,a,b,c,57);   R3(c,d,e,a,b,58);   R3(b,c,d,e,a,59); 
    
    R4(a,b,c,d,e,60);   R4(e,a,b,c,d,61);   R4(d,e,a,b,c,62);   R4(c,d,e,a,b,63); 
    
    R4(b,c,d,e,a,64);   R4(a,b,c,d,e,65);   R4(e,a,b,c,d,66);   R4(d,e,a,b,c,67); 
    
    R4(c,d,e,a,b,68);   R4(b,c,d,e,a,69);   R4(a,b,c,d,e,70);   R4(e,a,b,c,d,71); 
    
    R4(d,e,a,b,c,72);   R4(c,d,e,a,b,73);   R4(b,c,d,e,a,74);   R4(a,b,c,d,e,75); 
    
    R4(e,a,b,c,d,76);   R4(d,e,a,b,c,77);   R4(c,d,e,a,b,78);   R4(b,c,d,e,a,79); 
    
    /*   Add   the   working   vars   back   into   context.state[]   */ 
    
    state[0]   +=   a; 
    
    state[1]   +=   b; 
    
    state[2]   +=   c; 
    
    state[3]   +=   d; 
    
    state[4]   +=   e; 
    
    /*   Wipe   variables   */ 
    
    a   =   b   =   c   =   d   =   e   =   0; 
    
} 
/*   SHA1Init   -   Initialize   new   context   */ 


void   SHA1Init(SHA1_CTX*   context) 

{ 
    
    /*   SHA1   initialization   constants   */ 
    
    context-> state[0]   =   0x67452301; 
    
    context-> state[1]   =   0xEFCDAB89; 
    
    context-> state[2]   =   0x98BADCFE; 
    
    context-> state[3]   =   0x10325476; 
    
    context-> state[4]   =   0xC3D2E1F0; 
    
    context-> count[0]   =   context-> count[1]   =   0; 
    
} 


/*   Run   your   data   through   this.   */ 


void   SHA1Update(SHA1_CTX*   context,   unsigned   char*   data,   unsigned   int   len) 

{ 
    
    unsigned   int   i,   j; 
    
    
    j   =   (context-> count[0]   >>   3)   &   63; 
    
    if   ((context-> count[0]   +=   len   <<   3)   <   (len   <<   3))   context-> count[1]++;
    
    context-> count[1]   +=   (len   >>   29); 
    
    if   ((j   +   len)   >   63)   { 
        
        memcpy(&context-> buffer[j],   data,   (i   =   64-j)); 
        
        SHA1Transform(context-> state,   context-> buffer); 
        
        for   (   ;   i   +   63   <   len;   i   +=   64)   { 
            
            SHA1Transform(context-> state,   &data[i]); 
            
        } 
        
        j   =   0; 
        
    } 
    
    else   i   =   0; 
    
    memcpy(&context-> buffer[j],   &data[i],   len   -   i); 
    
} 


/*   Add   padding   and   return   the   message   digest.   */ 


void   SHA1Final(unsigned   char   digest[20],   SHA1_CTX*   context) 

{ 
    
    unsigned   long   i,   j; 
    
    unsigned   char   finalcount[8]; 
    
    
    for   (i   =   0;   i   <   8;   i++)   { 
        
        finalcount[i]   =   (unsigned   char)((context-> count[(i   >=   4   ?   0   :   1)] 
                                               
                                               >>   ((3-(i   &   3))   *   8)   )   &   255);     /*   Endian   independent   */ 
        
    } 
    
    SHA1Update(context,   (unsigned   char   *) "\200 ",   1); 
    
    while   ((context-> count[0]   &   504)   !=   448)   { 
        
        SHA1Update(context,   (unsigned   char   *) "\0 ",   1); 
        
    } 
    
    SHA1Update(context,   finalcount,   8);     /*   Should   cause   a   SHA1Transform()   */ 
    
    for   (i   =   0;   i   <   20;   i++)   { 
        
        digest[i]   =   (unsigned   char) 
        
        ((context-> state[i>> 2]   >>   ((3-(i   &   3))   *   8)   )   &   255); 
        
    } 
    
    /*   Wipe   variables   */ 
    
    i   =   j   =   0; 
    
    memset(context-> buffer,   0,   64); 
    
    memset(context-> state,   0,   20); 
    
    memset(context-> count,   0,   8); 
    
    memset(&finalcount,   0,   8); 
    
#ifdef   SHA1HANDSOFF     /*   make   SHA1Transform   overwrite   it 's   own   static   vars   */ 
    
    SHA1Transform(context-> state,   context-> buffer); 
    
#endif 
    
} 


/*************************************************************/ 


int   main(int   argc,   char**   argv) 

{ 
    
    int   i,   j; 
    
    SHA1_CTX   context; 
    
    unsigned   char   digest[20],   buffer[16384]; 
    
    FILE*   file; 
    
    
    if   (argc   >   2)   { 
        
        puts( "Public   domain   SHA-1   implementation   -   by   Steve   Reid   <steve@edmweb.com> "); 
        
        puts( "Produces   the   SHA-1   hash   of   a   file,   or   stdin   if   no   file   is   specified. "); 
        
        exit(0); 
        
    } 
    
    if   (argc   <   2)   { 
        
        file   =   stdin; 
        
    } 
    
    else   { 
        
        if   (!(file   =   fopen(argv[1],   "rb ")))   { 
            
            fputs( "Unable   to   open   file. ",   stderr); 
            
            exit(-1); 
            
        } 
        
    }   
    
    SHA1Init(&context); 
    
    while   (!feof(file))   {     /*   note:   what   if   ferror(file)   */ 
        
        i   =   fread(buffer,   1,   16384,   file); 
        
        SHA1Update(&context,   buffer,   i); 
        
    } 
    
    SHA1Final(digest,   &context); 
    
    fclose(file); 
    
    for   (i   =   0;   i   <   5;   i++)   { 
        
        for   (j   =   0;   j   <   4;   j++)   { 
            
            printf( "%02X ",   digest[i*4+j]); 
            
        } 
        
        putchar(' '); 
        
    } 
    
    putchar('\n'); 
    
    exit(0); 
    
} 
分享到:
评论

相关推荐

    sha 算法c语言实现

    在标题“SHA算法C语言实现”中,我们关注的是如何使用C语言编写代码来实现SHA算法。C语言是一种底层、通用且高效的编程语言,适合编写这样的底层算法实现。 描述中提到“编译成功,并在nrf52832上验证”,nrf52832...

    SHA-1算法c语言实现

    在C语言中实现SHA-1算法,需要理解算法的内部工作原理并将其转化为一系列的C语言语句和数据结构。 SHA-1算法的步骤主要包括初始化、处理消息块和生成摘要。首先,算法初始化五个32位的中间变量,接着将输入消息划分...

    SHA-1_hashsha-1_sha-1_SHA-1算法的C语言实现_

    通过编写SHA-1的C语言实现,学生不仅可以掌握哈希函数的基本概念,还能提升在低级别语言中解决问题的能力。这对于理解其他更复杂的密码学算法,如SHA-256、SHA-3等,以及后续深入研究网络安全和密码学都是有益的。...

    sha1算法的代码实现

    SHA1在1995年发布,作为SHA-0的增强版,但在2011年后被认为不再安全,因为出现了可以碰撞攻击的理论方法。 SHA1算法的核心步骤包括初始化、处理消息块、生成中间结果和最终散列值。其主要过程如下: 1. **初始化**...

    SHA256算法C++代码openssl库实现

    对sha256在openssl库中调用和组装生成可以执行的基于openssl库的sha256模块,可供之后的生日攻击和长度扩展攻击等使用该模块。 可以运行test.cpp对该模块的散列加密功能进行简单测试。 运行指导 将源码clone到...

    SHA1算法.zip

    在编程语言C中,实现SHA1算法通常涉及到以下步骤: 1. 定义结构体存储中间和最终的哈希值。 2. 编写消息扩张和压缩函数的具体实现。 3. 将输入消息分割为适当大小的块,逐块处理。 4. 最后组合所有的中间结果得到...

    Hmac算法c语言实现

    在C语言中,你可以使用开源库如OpenSSL提供的`EVP_DigestInit`, `EVP_DigestUpdate`和`EVP_DigestFinal`系列函数来实现SHA-1、SHA-256等哈希函数。 2. **预处理密钥**:HMAC算法要求密钥首先进行处理,以便适应所选...

    sha1sum校验算法及代码实现

    当你下载或传输文件后,可以通过计算文件的SHA1摘要并与原始源的SHA1值对比,来判断文件是否在传输过程中被篡改或损坏。 3. **Windows环境下的实现**:在Windows系统中,可以使用命令行工具`certutil`来计算文件的...

    sha.rar_SHA_SHA-1算法的 C语言实现

    SHA算法,全称为Secure Hash Algorithm,是一种广泛应用于信息安全领域的加密散列函数,旨在为数据提供一个固定长度的、唯一的“指纹”。SHA-1是SHA家族中的一个版本,它在1995年由美国国家安全局(NSA)设计,并由...

    SHA-1算法实现源代码

    在C++中实现SHA-1算法通常涉及到对原始输入数据进行一系列复杂的数学运算,包括位操作、加法、异或和模运算。 SHA-1算法的步骤大致分为以下几个部分: 1. **初始化变量**:算法开始时,设置四个32位的中间变量A、B...

    SHA256 C源码.zip

    在给定的"SHA256 C源码.zip"压缩包中,我们可以期待找到一个C语言实现的SHA256算法。C语言是一种底层编程语言,非常适合编写这样的核心算法,因为它可以提供高效的内存管理和直接访问硬件资源的能力。 SHA256算法...

    FIPS 180-2 散列算法SHA-224、SHA-256、SHA-384 和 SHA-512 的C语言快速软件实施

    压缩包中的"sha2-master"可能是一个项目仓库的名称,通常在GitHub等版本控制系统中,"master"分支代表项目的主分支,里面包含了完整的SHA-2算法的C语言源代码,开发者可以下载并根据需求进行编译和使用。 总的来说...

    HMAC加密算法C语言版本

    HMAC加密算法C语言版本,支持EVP_md5(), EVP_sha224, EVP_sha512, etc等

    用C++实现SHA-2算法家族

    它由美国国家安全局(NSA)开发,包括SHA-224、SHA-256、SHA-384、SHA-512以及它们的变种SHA512_224和SHA512_256。C++是一种通用的、面向对象的编程语言,以其灵活性和高效性而被广泛应用在系统和应用软件开发中。 ...

    Debug_c_sha-1_

    在"Debug_c_sha-1_"项目中,我们可以推测这是一个用C语言实现的SHA-1算法调试版本。调试版本的目的是在开发过程中检查和修复代码错误,确保程序的正确性和可靠性。开发者可能已经添加了断点、日志输出或其他调试工具...

    典型密码算法及其C语言实现_附录代码实现

    MD5(Message-Digest Algorithm 5)和SHA-1(Secure Hash Algorithm 1)曾是广泛使用的哈希函数,但由于安全性问题,现在已被SHA-2(如SHA-256和SHA-512)等更安全的算法替代。 4. 数字签名:数字签名结合了非对称...

    lua_sha1.rar

    在Lua编程语言中,尽管没有内置的SHA1实现,但我们可以利用Lua的灵活性编写自定义的SHA1算法。"lua_sha1.rar"这个压缩包就包含了这样一个用Lua编写的SHA1加密库。 SHA1算法的原理是通过一系列的数学运算(如位移、...

    sha.rar_SHA_SHA1_starts_sha-1_sha-2

    而"sha"文件可能是实现SHA算法的C语言或其他编程语言的源代码文件,里面包含了计算哈希值的具体函数和流程。 学习和理解这些源代码可以帮助我们深入理解哈希函数的工作原理,包括如何处理输入数据,如何通过迭代...

    nullsha-1算法的C实现.doc

    《SHA-1算法的C实现》 SHA-1(Secure Hash Algorithm 1)是一种广泛使用的密码散列函数,设计用于数字签名和消息认证代码(MAC)。它的主要功能是将任意长度的信息转化为固定长度的摘要,通常是一个160位(20字节)...

    Hash-MD5算法(C语言实现,附带Hash验证工具)

    了解并掌握MD5算法的实现和使用,对于理解和编写其他哈希函数,如SHA-1、SHA-256等,都是很有帮助的。同时,学习C语言实现的MD5算法,可以深入理解底层的计算过程,有助于提升编程和算法分析能力。在实际项目中,你...

Global site tag (gtag.js) - Google Analytics