• sha1 算法源码


    原来指望sha1 这种烂大街的算法 不会出什么幺蛾子 结果《linux C编程实战Code》bt章节的sha1 代码 我在linux和windows下的结果不一样

    然后用了哈希工具查看了下 发现结果也不一样。 windows和linux自带工具是一致的,但是和《linux C编程实战Code》的代码 无论在windows还是linux下都不一致

    这里记录下新得代码 以后备用 (unbuntu wndows7 下执行 计算结果一致)

     1 /*
     2 * sha1.h
     3 *
     4 * Description:
     5 * This is the header file for code which implements the Secure
     6 * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
     7 * April 17, 1995.
     8 *
     9 * Many of the variable names in this code, especially the
    10 * single character names, were used because those were the names
    11 * used in the publication.
    12 *
    13 * Please read the file sha1.c for more information.
    14 *
    15 */
    16 
    17 #ifndef _SHA1_H_
    18 #define _SHA1_H_
    19 #include <stdint.h>
    20 /*
    21 * If you do not have the ISO standard stdint.h header file, then you
    22 * must typdef the following:
    23 * name meaning
    24 * uint32_t unsigned 32 bit integer
    25 * uint8_t unsigned 8 bit integer (i.e., unsigned char)
    26 * int_least16_t integer of >= 16 bits
    27 *
    28 */
    29 #ifndef _SHA_enum_
    30 #define _SHA_enum_
    31 enum
    32 {
    33     shaSuccess = 0,
    34     shaNull,         /* Null pointer parameter */
    35     shaInputTooLong, /* input data too long */
    36     shaStateError    /* called Input after Result */
    37 };
    38 #endif
    39 #define SHA1HashSize 20
    40 /*
    41 * This structure will hold context information for the SHA-1
    42 * hashing operation
    43 */
    44 typedef struct SHA1Context
    45 {
    46     uint32_t Intermediate_Hash[SHA1HashSize / 4]; /* Message Digest */
    47     uint32_t Length_Low; /* Message length in bits */
    48     uint32_t Length_High; /* Message length in bits */
    49     /* Index into message block array */
    50     int_least16_t Message_Block_Index;
    51     uint8_t Message_Block[64]; /* 512-bit message blocks */
    52     int Computed; /* Is the digest computed? */
    53     int Corrupted; /* Is the message digest corrupted? */
    54 } SHA1Context;
    55 
    56 
    57 /*
    58 * Function Prototypes
    59 */
    60 
    61 int SHA1Reset(SHA1Context *);
    62 int SHA1Input(SHA1Context *, const uint8_t *, unsigned int);
    63 int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize]);
    64 
    65 #endif
    sha1.h
      1 /*
      2 * sha1.c
      3 *
      4 * Description:
      5 * This file implements the Secure Hashing Algorithm 1 as
      6 * defined in FIPS PUB 180-1 published April 17, 1995.
      7 *
      8 * The SHA-1, produces a 160-bit message digest for a given
      9 * data stream. It should take about 2**n steps to find a
     10 * message with the same digest as a given message and
     11 * 2**(n/2) to find any two messages with the same digest,
     12 * when n is the digest size in bits. Therefore, this
     13 * algorithm can serve as a means of providing a
     14 * "fingerprint" for a message.
     15 *
     16 * Portability Issues:
     17 * SHA-1 is defined in terms of 32-bit "words". This code
     18 * uses <stdint.h> (included via "sha1.h" to define 32 and 8
     19 * bit unsigned integer types. If your C compiler does not
     20 * support 32 bit unsigned integers, this code is not
     21 * appropriate.
     22 *
     23 * Caveats:
     24 * SHA-1 is designed to work with messages less than 2^64 bits
     25 * long. Although SHA-1 allows a message digest to be generated
     26 * for messages of any number of bits less than 2^64, this
     27 * implementation only works with messages with a length that is
     28 * a multiple of the size of an 8-bit character.
     29 *
     30 */
     31  
     32 #include "SHA1.h"
     33 
     34 #ifdef __cplusplus
     35 extern "C"
     36 {
     37 #endif
     38 
     39     /*
     40     * Define the SHA1 circular left shift macro
     41     */
     42 #define SHA1CircularShift(bits,word) 
     43     (((word) << (bits)) | ((word) >> (32-(bits))))
     44     /* Local Function Prototyptes */
     45     void SHA1PadMessage(SHA1Context *);
     46     void SHA1ProcessMessageBlock(SHA1Context *);
     47     /*
     48     * SHA1Reset
     49     *
     50     * Description:
     51     * This function will initialize the SHA1Context in preparation
     52     * for computing a new SHA1 message digest.
     53     *
     54     * Parameters:
     55     * context: [in/out]
     56     * The context to reset.
     57     *
     58     * Returns:
     59     * sha Error Code.
     60     *
     61     */
     62     int SHA1Reset(SHA1Context *context)//初始化状态
     63     {
     64         if (!context)
     65         {
     66             return shaNull;
     67         }
     68         context->Length_Low = 0;
     69         context->Length_High = 0;
     70         context->Message_Block_Index = 0;
     71         context->Intermediate_Hash[0] = 0x67452301;//取得的HASH结果(中间数据)
     72         context->Intermediate_Hash[1] = 0xEFCDAB89;
     73         context->Intermediate_Hash[2] = 0x98BADCFE;
     74         context->Intermediate_Hash[3] = 0x10325476;
     75         context->Intermediate_Hash[4] = 0xC3D2E1F0;
     76         context->Computed = 0;
     77         context->Corrupted = 0;
     78         return shaSuccess;
     79     }
     80 
     81 
     82     /*
     83     * SHA1Result
     84     *
     85     * Description:
     86     * This function will return the 160-bit message digest into the
     87     * Message_Digest array provided by the caller.
     88     * NOTE: The first octet of hash is stored in the 0th element,
     89     * the last octet of hash in the 19th element.
     90     *
     91     * Parameters:
     92     * context: [in/out]
     93     * The context to use to calculate the SHA-1 hash.
     94     * Message_Digest: [out]
     95     * Where the digest is returned.
     96     *
     97     * Returns:
     98     * sha Error Code.
     99     *
    100     */
    101     int SHA1Result(SHA1Context *context, uint8_t Message_Digest[SHA1HashSize])
    102     {
    103         int i;
    104         if (!context || !Message_Digest)
    105         {
    106             return shaNull;
    107         }
    108         if (context->Corrupted)
    109         {
    110             return context->Corrupted;
    111         }
    112         if (!context->Computed)
    113         {
    114             SHA1PadMessage(context);
    115             for (i = 0; i < 64; ++i)
    116             {
    117                 /* message may be sensitive, clear it out */
    118                 context->Message_Block[i] = 0;
    119             }
    120             context->Length_Low = 0; /* and clear length */
    121             context->Length_High = 0;
    122             context->Computed = 1;
    123         }
    124         for (i = 0; i < SHA1HashSize; ++i)
    125         {
    126             Message_Digest[i] = context->Intermediate_Hash[i >> 2]
    127                 >> 8 * (3 - (i & 0x03));
    128         }
    129         return shaSuccess;
    130     }
    131 
    132 
    133     /*
    134     * SHA1Input
    135     *
    136     * Description:
    137     * This function accepts an array of octets as the next portion
    138     * of the message.
    139     *
    140     * Parameters:
    141     * context: [in/out]
    142     * The SHA context to update
    143     * message_array: [in]
    144     * An array of characters representing the next portion of
    145     * the message.
    146     * length: [in]
    147     * The length of the message in message_array
    148     *
    149     * Returns:
    150     * sha Error Code.
    151     *
    152     */
    153 
    154     int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned length)
    155     {
    156         if (!length)
    157         {
    158             return shaSuccess;
    159         }
    160         if (!context || !message_array)
    161         {
    162             return shaNull;
    163         }
    164         if (context->Computed)
    165         {
    166             context->Corrupted = shaStateError;
    167             return shaStateError;
    168         }
    169         if (context->Corrupted)
    170         {
    171             return context->Corrupted;
    172         }
    173         while (length-- && !context->Corrupted)
    174         {
    175             context->Message_Block[context->Message_Block_Index++] =
    176                 (*message_array & 0xFF);
    177             context->Length_Low += 8;
    178             if (context->Length_Low == 0)
    179             {
    180                 context->Length_High++;
    181                 if (context->Length_High == 0)
    182                 {
    183                     /* Message is too long */
    184                     context->Corrupted = 1;
    185                 }
    186             }
    187             if (context->Message_Block_Index == 64)
    188             {
    189                 SHA1ProcessMessageBlock(context);
    190             }
    191             message_array++;
    192         }
    193         return shaSuccess;
    194     }
    195 
    196     /*
    197     * SHA1ProcessMessageBlock
    198     *
    199     * Description:
    200     * This function will process the next 512 bits of the message
    201     * stored in the Message_Block array.
    202     *
    203     * Parameters:
    204     * None.
    205     *
    206     * Returns:
    207     * Nothing.
    208     *
    209     * Comments:
    210     * Many of the variable names in this code, especially the
    211     * single character names, were used because those were the
    212     * names used in the publication.
    213     *
    214     */
    215 
    216     void SHA1ProcessMessageBlock(SHA1Context *context)
    217     {
    218         const uint32_t K[] = { /* Constants defined in SHA-1 */
    219             0x5A827999,
    220             0x6ED9EBA1,
    221             0x8F1BBCDC,
    222             0xCA62C1D6
    223         };
    224         int t; /* Loop counter */
    225         uint32_t temp; /* Temporary word value */
    226         uint32_t W[80]; /* Word sequence */
    227         uint32_t A, B, C, D, E; /* Word buffers */
    228         /*
    229         * Initialize the first 16 words in the array W
    230         */
    231         for (t = 0; t < 16; t++)
    232         {
    233             W[t] = context->Message_Block[t * 4] << 24;
    234             W[t] |= context->Message_Block[t * 4 + 1] << 16;
    235             W[t] |= context->Message_Block[t * 4 + 2] << 8;
    236             W[t] |= context->Message_Block[t * 4 + 3];
    237         }
    238         for (t = 16; t < 80; t++)
    239         {
    240             W[t] = SHA1CircularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
    241         }
    242         A = context->Intermediate_Hash[0];
    243         B = context->Intermediate_Hash[1];
    244         C = context->Intermediate_Hash[2];
    245         D = context->Intermediate_Hash[3];
    246         E = context->Intermediate_Hash[4];
    247         for (t = 0; t < 20; t++)
    248         {
    249             temp = SHA1CircularShift(5, A) +
    250                 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
    251             E = D;
    252             D = C;
    253             C = SHA1CircularShift(30, B);
    254             B = A;
    255             A = temp;
    256         }
    257         for (t = 20; t < 40; t++)
    258         {
    259             temp = SHA1CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1];
    260             E = D;
    261             D = C;
    262             C = SHA1CircularShift(30, B);
    263             B = A;
    264             A = temp;
    265         }
    266         for (t = 40; t < 60; t++)
    267         {
    268             temp = SHA1CircularShift(5, A) +
    269                 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
    270             E = D;
    271             D = C;
    272             C = SHA1CircularShift(30, B);
    273             B = A;
    274             A = temp;
    275         }
    276         for (t = 60; t < 80; t++)
    277         {
    278             temp = SHA1CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3];
    279             E = D;
    280             D = C;
    281             C = SHA1CircularShift(30, B);
    282             B = A;
    283             A = temp;
    284         }
    285         context->Intermediate_Hash[0] += A;
    286         context->Intermediate_Hash[1] += B;
    287         context->Intermediate_Hash[2] += C;
    288         context->Intermediate_Hash[3] += D;
    289         context->Intermediate_Hash[4] += E;
    290         context->Message_Block_Index = 0;
    291     }
    292 
    293 
    294     /*
    295     * SHA1PadMessage
    296     *
    297     * Description:
    298     * According to the standard, the message must be padded to an even
    299     * 512 bits. The first padding bit must be a ’1’. The last 64
    300     * bits represent the length of the original message. All bits in
    301     * between should be 0. This function will pad the message
    302     * according to those rules by filling the Message_Block array
    303     * accordingly. It will also call the ProcessMessageBlock function
    304     * provided appropriately. When it returns, it can be assumed that
    305     * the message digest has been computed.
    306     *
    307     * Parameters:
    308     * context: [in/out]
    309     * The context to pad
    310     * ProcessMessageBlock: [in]
    311     * The appropriate SHA*ProcessMessageBlock function
    312     * Returns:
    313     * Nothing.
    314     *
    315     */
    316 
    317     void SHA1PadMessage(SHA1Context *context)
    318     {
    319         /*
    320         * Check to see if the current message block is too small to hold
    321         * the initial padding bits and length. If so, we will pad the
    322         * block, process it, and then continue padding into a second
    323         * block.
    324         */
    325         if (context->Message_Block_Index > 55)
    326         {
    327             context->Message_Block[context->Message_Block_Index++] = 0x80;
    328             while (context->Message_Block_Index < 64)
    329             {
    330                 context->Message_Block[context->Message_Block_Index++] = 0;
    331             }
    332             SHA1ProcessMessageBlock(context);
    333             while (context->Message_Block_Index < 56)
    334             {
    335                 context->Message_Block[context->Message_Block_Index++] = 0;
    336             }
    337         }
    338         else
    339         {
    340             context->Message_Block[context->Message_Block_Index++] = 0x80;
    341             while (context->Message_Block_Index < 56)
    342             {
    343                 context->Message_Block[context->Message_Block_Index++] = 0;
    344             }
    345         }
    346 
    347         /*
    348         * Store the message length as the last 8 octets
    349         */
    350         context->Message_Block[56] = context->Length_High >> 24;
    351         context->Message_Block[57] = context->Length_High >> 16;
    352         context->Message_Block[58] = context->Length_High >> 8;
    353         context->Message_Block[59] = context->Length_High;
    354         context->Message_Block[60] = context->Length_Low >> 24;
    355         context->Message_Block[61] = context->Length_Low >> 16;
    356         context->Message_Block[62] = context->Length_Low >> 8;
    357         context->Message_Block[63] = context->Length_Low;
    358         SHA1ProcessMessageBlock(context);
    359     }
    360 
    361 
    362 #ifdef __cplusplus
    363 }
    364 #endif
    sha1.c
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Java面试之对象拷贝
    Java面试之反射
    Java面试之多线程
    Java面试之容器
    Java面试之基础一
    Java面试之Hibernate
    Mysql进阶
    高并发,不怕不怕「限流算法第一把法器:计数器法」
    SpringBoot加载速度慢
    idea VM options参数优化
  • 原文地址:https://www.cnblogs.com/itdef/p/9927640.html
Copyright © 2020-2023  润新知