原来指望sha1 这种烂大街的算法 不会出什么幺蛾子 结果《linux C编程实战Code》bt章节的sha1 代码 我在linux和windows下的结果不一样
然后用了哈希工具查看了下 发现结果也不一样。 windows和linux自带工具是一致的,但是和《linux C编程实战Code》的代码 无论在windows还是linux下都不一致
这里记录下新得代码 以后备用 (unbuntu wndows7 下执行 计算结果一致)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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