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驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/9927640.html