MD5和SHA1算法的C++实现和使用

56 篇文章 5 订阅

MD5算法:


MD5.H

[cpp]  view plain  copy
  1. #ifndef MD5_H  
  2. #define MD5_H  
  3.   
  4.   
  5. typedef struct  
  6. {  
  7.   unsigned int count[2];  
  8.   unsigned int state[4];  
  9.   unsigned char buffer[64];  
  10. } MD5_CTX;  
  11.   
  12. #define F(x,y,z) ((x & y) | (~x & z))  
  13. #define G(x,y,z) ((x & z) | (y & ~z))  
  14. #define H(x,y,z) (x^y^z)  
  15. #define I(x,y,z) (y ^ (x | ~z))  
  16. #define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))  
  17.   
  18. #define FF(a,b,c,d,x,s,ac) \  
  19. { \  
  20.   a += F(b,c,d) + x + ac; \  
  21.   a = ROTATE_LEFT(a,s); \  
  22.   a += b; \  
  23. }  
  24. #define GG(a,b,c,d,x,s,ac) \  
  25. { \  
  26.   a += G(b,c,d) + x + ac; \  
  27.   a = ROTATE_LEFT(a,s); \  
  28.   a += b; \  
  29. }  
  30. #define HH(a,b,c,d,x,s,ac) \  
  31. { \  
  32.   a += H(b,c,d) + x + ac; \  
  33.   a = ROTATE_LEFT(a,s); \  
  34.   a += b; \  
  35. }  
  36. #define II(a,b,c,d,x,s,ac) \  
  37. { \  
  38.   a += I(b,c,d) + x + ac; \  
  39.   a = ROTATE_LEFT(a,s); \  
  40.   a += b; \  
  41. }  
  42. void MD5Init(MD5_CTX *context);  
  43. void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);  
  44. void MD5Final(MD5_CTX *context, unsigned char digest[16]);  
  45. void MD5Transform(unsigned int state[4], unsigned char block[64]);  
  46. void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);  
  47. void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);  
  48.   
  49. #endif  


MD5.CPP

[cpp]  view plain  copy
  1. #include "md5.h"  
  2. #include <memory.h>  
  3. #include <stdlib.h>  
  4. #include <stdio.h>  
  5. #include<fcntl.h>  
  6. unsigned char PADDING[] =  
  7. {  
  8.   0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
  9.   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
  10.   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
  11.   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  
  12. };  
  13.   
  14. void MD5Init(MD5_CTX *context)  
  15. {  
  16.   context->count[0] = 0;  
  17.   context->count[1] = 0;  
  18.   context->state[0] = 0x67452301;  
  19.   context->state[1] = 0xEFCDAB89;  
  20.   context->state[2] = 0x98BADCFE;  
  21.   context->state[3] = 0x10325476;  
  22. }  
  23.   
  24. void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen)  
  25. {  
  26.   unsigned int i = 0;  
  27.   unsigned int index = 0;  
  28.   unsigned int partlen = 0;  
  29.   
  30.   index = (context->count[0] >> 3) & 0x3F;  
  31.   partlen = 64 - index;  
  32.   context->count[0] += inputlen << 3;  
  33.   
  34.   if(context->count[0] < (inputlen << 3))  
  35.     context->count[1]++;  
  36.   context->count[1] += inputlen >> 29;  
  37.   
  38.   if(inputlen >= partlen)  
  39.   {  
  40.     memcpy(&context->buffer[index], input,partlen);  
  41.     MD5Transform(context->state, context->buffer);  
  42.   
  43.     for(i = partlen; i+64 <= inputlen; i+=64)  
  44.       MD5Transform(context->state, &input[i]);  
  45.   
  46.     index = 0;  
  47.   }  
  48.   else  
  49.   {  
  50.     i = 0;  
  51.   }  
  52.   memcpy(&context->buffer[index], &input[i], inputlen-i);  
  53. }  
  54.   
  55. void MD5Final(MD5_CTX *context, unsigned char digest[16])  
  56. {  
  57.   unsigned int index = 0,padlen = 0;  
  58.   unsigned char bits[8];  
  59.   
  60.   index = (context->count[0] >> 3) & 0x3F;  
  61.   padlen = (index < 56)?(56-index):(120-index);  
  62.   MD5Encode(bits, context->count, 8);  
  63.   MD5Update(context, PADDING, padlen);  
  64.   MD5Update(context, bits, 8);  
  65.   MD5Encode(digest, context->state, 16);  
  66. }  
  67.   
  68. void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)  
  69. {  
  70.   unsigned int i = 0;  
  71.   unsigned int j = 0;  
  72.   
  73.   while(j < len)  
  74.   {  
  75.     output[j] = input[i] & 0xFF;  
  76.     output[j+1] = (input[i] >> 8) & 0xFF;  
  77.     output[j+2] = (input[i] >> 16) & 0xFF;  
  78.     output[j+3] = (input[i] >> 24) & 0xFF;  
  79.     i++;  
  80.     j += 4;  
  81.   }  
  82. }  
  83.   
  84. void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)  
  85. {  
  86.   unsigned int i = 0;  
  87.   unsigned int j = 0;  
  88.   
  89.   while(j < len)  
  90.   {  
  91.     output[i] = (input[j]) |  
  92.       (input[j+1] << 8) |  
  93.       (input[j+2] << 16) |  
  94.       (input[j+3] << 24);  
  95.     i++;  
  96.     j += 4;  
  97.   }  
  98. }  
  99.   
  100. void MD5Transform(unsigned int state[4], unsigned char block[64])  
  101. {  
  102.   unsigned int a = state[0];  
  103.   unsigned int b = state[1];  
  104.   unsigned int c = state[2];  
  105.   unsigned int d = state[3];  
  106.   unsigned int x[64];  
  107.   
  108.   MD5Decode(x,block,64);  
  109.   
  110.   FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */  
  111.   FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */  
  112.   FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */  
  113.   FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */  
  114.   FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */  
  115.   FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */  
  116.   FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */  
  117.   FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */  
  118.   FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */  
  119.   FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */  
  120.   FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */  
  121.   FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */  
  122.   FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */  
  123.   FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */  
  124.   FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */  
  125.   FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */  
  126.   
  127.   /* Round 2 */  
  128.   GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */  
  129.   GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */  
  130.   GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */  
  131.   GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */  
  132.   GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */  
  133.   GG(d, a, b, c, x[10], 9,  0x2441453); /* 22 */  
  134.   GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */  
  135.   GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */  
  136.   GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */  
  137.   GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */  
  138.   GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */  
  139.   GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */  
  140.   GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */  
  141.   GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */  
  142.   GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */  
  143.   GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */  
  144.   
  145.   /* Round 3 */  
  146.   HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */  
  147.   HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */  
  148.   HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */  
  149.   HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */  
  150.   HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */  
  151.   HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */  
  152.   HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */  
  153.   HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */  
  154.   HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */  
  155.   HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */  
  156.   HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */  
  157.   HH(b, c, d, a, x[ 6], 23,  0x4881d05); /* 44 */  
  158.   HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */  
  159.   HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */  
  160.   HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */  
  161.   HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */  
  162.   
  163.   /* Round 4 */  
  164.   II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */  
  165.   II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */  
  166.   II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */  
  167.   II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */  
  168.   II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */  
  169.   II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */  
  170.   II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */  
  171.   II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */  
  172.   II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */  
  173.   II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */  
  174.   II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */  
  175.   II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */  
  176.   II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */  
  177.   II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */  
  178.   II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */  
  179.   II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */  
  180.   state[0] += a;  
  181.   state[1] += b;  
  182.   state[2] += c;  
  183.   state[3] += d;  
  184. }  


获取文件的MD5值的实现和基本使用


实现

[cpp]  view plain  copy
  1. int GetFileMD5(const char* filePath, char* strMD5)  
  2. {  
  3.     int i;  
  4.     int fd;  
  5.     int ret;  
  6.     unsigned char data[READ_DATA_SIZE];  
  7.     unsigned char md5_value[MD5_SIZE];  
  8.     MD5_CTX md5;  
  9.   
  10.     fd = open(filePath, O_RDONLY);  
  11.     if (-1 == fd)  
  12.     {  
  13.         perror("open");  
  14.         return -1;  
  15.     }  
  16.   
  17.     // init md5  
  18.     MD5Init(&md5);  
  19.   
  20.     while (1)  
  21.     {  
  22.         ret = read(fd, data, READ_DATA_SIZE);  
  23.         if (-1 == ret)  
  24.         {  
  25.             perror("read");  
  26.             close(fd);  
  27.             return -1;  
  28.         }  
  29.   
  30.         MD5Update(&md5, data, ret);  
  31.   
  32.         if (0 == ret || ret < READ_DATA_SIZE)  
  33.         {  
  34.             break;  
  35.         }  
  36.     }  
  37.   
  38.     close(fd);  
  39.   
  40.     MD5Final(&md5, md5_value);  
  41.   
  42.     for (i = 0; i < MD5_SIZE; i++)  
  43.     {  
  44.         snprintf(strMD5 + i * 2, 2 + 1, "%02x", md5_value[i]);  
  45.     }  
  46.     strMD5[MD5_STR_LEN] = '\0'// add end  
  47.     return 0;  
  48. }  


调用:

[cpp]  view plain  copy
  1. char backfile_md5_str[33];  
  2. GetFileMD5(m_strBackupFile.c_str(), backfile_md5_str);  

SHA1算法的实现和基本使用


SHA1.h

[cpp]  view plain  copy
  1. /* 
  2.   100% free public domain implementation of the SHA-1 algorithm 
  3.   by Dominik Reichl <dominik.reichl@t-online.de> 
  4.   Web: http://www.dominik-reichl.de/ 
  5.  
  6.   Version 2.1 - 2012-06-19 
  7.   - Deconstructor (resetting internal variables) is now only 
  8.     implemented if SHA1_WIPE_VARIABLES is defined (which is the 
  9.     default). 
  10.   - Renamed inclusion guard to contain a GUID. 
  11.   - Demo application is now using C++/STL objects and functions. 
  12.   - Unicode build of the demo application now outputs the hashes of both 
  13.     the ANSI and Unicode representations of strings. 
  14.   - Various other demo application improvements. 
  15.  
  16.   Version 2.0 - 2012-06-14 
  17.   - Added 'limits.h' include. 
  18.   - Renamed inclusion guard and macros for compliancy (names beginning 
  19.     with an underscore are reserved). 
  20.  
  21.   Version 1.9 - 2011-11-10 
  22.   - Added Unicode test vectors. 
  23.   - Improved support for hashing files using the HashFile method that 
  24.     are larger than 4 GB. 
  25.   - Improved file hashing performance (by using a larger buffer). 
  26.   - Disabled unnecessary compiler warnings. 
  27.   - Internal variables are now private. 
  28.  
  29.   Version 1.8 - 2009-03-16 
  30.   - Converted project files to Visual Studio 2008 format. 
  31.   - Added Unicode support for HashFile utility method. 
  32.   - Added support for hashing files using the HashFile method that are 
  33.     larger than 2 GB. 
  34.   - HashFile now returns an error code instead of copying an error 
  35.     message into the output buffer. 
  36.   - GetHash now returns an error code and validates the input parameter. 
  37.   - Added ReportHashStl STL utility method. 
  38.   - Added REPORT_HEX_SHORT reporting mode. 
  39.   - Improved Linux compatibility of test program. 
  40.  
  41.   Version 1.7 - 2006-12-21 
  42.   - Fixed buffer underrun warning that appeared when compiling with 
  43.     Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the 
  44.     patch). 
  45.   - Breaking change: ReportHash writes the final hash to the start 
  46.     of the buffer, i.e. it's not appending it to the string anymore. 
  47.   - Made some function parameters const. 
  48.   - Added Visual Studio 2005 project files to demo project. 
  49.  
  50.   Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) 
  51.   - You can set the endianness in your files, no need to modify the 
  52.     header file of the CSHA1 class anymore. 
  53.   - Aligned data support. 
  54.   - Made support/compilation of the utility functions (ReportHash and 
  55.     HashFile) optional (useful when bytes count, for example in embedded 
  56.     environments). 
  57.  
  58.   Version 1.5 - 2005-01-01 
  59.   - 64-bit compiler compatibility added. 
  60.   - Made variable wiping optional (define SHA1_WIPE_VARIABLES). 
  61.   - Removed unnecessary variable initializations. 
  62.   - ROL32 improvement for the Microsoft compiler (using _rotl). 
  63.  
  64.   Version 1.4 - 2004-07-22 
  65.   - CSHA1 now compiles fine with GCC 3.3 under Mac OS X (thanks to Larry 
  66.     Hastings). 
  67.  
  68.   Version 1.3 - 2003-08-17 
  69.   - Fixed a small memory bug and made a buffer array a class member to 
  70.     ensure correct working when using multiple CSHA1 class instances at 
  71.     one time. 
  72.  
  73.   Version 1.2 - 2002-11-16 
  74.   - Borlands C++ compiler seems to have problems with string addition 
  75.     using sprintf. Fixed the bug which caused the digest report function 
  76.     not to work properly. CSHA1 is now Borland compatible. 
  77.  
  78.   Version 1.1 - 2002-10-11 
  79.   - Removed two unnecessary header file includes and changed BOOL to 
  80.     bool. Fixed some minor bugs in the web page contents. 
  81.  
  82.   Version 1.0 - 2002-06-20 
  83.   - First official release. 
  84.  
  85.   ================ Test Vectors ================ 
  86.  
  87.   SHA1("abc" in ANSI) = 
  88.     A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 
  89.   SHA1("abc" in Unicode LE) = 
  90.     9F04F41A 84851416 2050E3D6 8C1A7ABB 441DC2B5 
  91.  
  92.   SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 
  93.     in ANSI) = 
  94.     84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 
  95.   SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 
  96.     in Unicode LE) = 
  97.     51D7D876 9AC72C40 9C5B0E3F 69C60ADC 9A039014 
  98.  
  99.   SHA1(A million repetitions of "a" in ANSI) = 
  100.     34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 
  101.   SHA1(A million repetitions of "a" in Unicode LE) = 
  102.     C4609560 A108A0C6 26AA7F2B 38A65566 739353C5 
  103. */  
  104.   
  105. #ifndef SHA1_H_A545E61D43E9404E8D736869AB3CBFE7  
  106. #define SHA1_H_A545E61D43E9404E8D736869AB3CBFE7  
  107.   
  108. #if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)  
  109. #define SHA1_UTILITY_FUNCTIONS  
  110. #endif  
  111.   
  112. #if !defined(SHA1_STL_FUNCTIONS) && !defined(SHA1_NO_STL_FUNCTIONS)  
  113. #define SHA1_STL_FUNCTIONS  
  114. #if !defined(SHA1_UTILITY_FUNCTIONS)  
  115. #error STL functions require SHA1_UTILITY_FUNCTIONS.  
  116. #endif  
  117. #endif  
  118.   
  119. #include <memory.h>  
  120. #include <limits.h>  
  121.   
  122. #ifdef SHA1_UTILITY_FUNCTIONS  
  123. #include <stdio.h>  
  124. #include <string.h>  
  125. #endif  
  126.   
  127. #ifdef SHA1_STL_FUNCTIONS  
  128. #include <string>  
  129. #endif  
  130.   
  131. #ifdef _MSC_VER  
  132. #include <stdlib.h>  
  133. #endif  
  134.   
  135. // You can define the endian mode in your files without modifying the SHA-1  
  136. // source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN  
  137. // in your files, before including the SHA1.h header file. If you don't  
  138. // define anything, the class defaults to little endian.  
  139. #if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)  
  140. #define SHA1_LITTLE_ENDIAN  
  141. #endif  
  142.   
  143. // If you want variable wiping, #define SHA1_WIPE_VARIABLES, if not,  
  144. // #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it  
  145. // defaults to wiping.  
  146. #if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)  
  147. #define SHA1_WIPE_VARIABLES  
  148. #endif  
  149.   
  150. #if defined(SHA1_HAS_TCHAR)  
  151. #include <tchar.h>  
  152. #else  
  153. #ifdef _MSC_VER  
  154. #include <tchar.h>  
  155. #else  
  156. #ifndef TCHAR  
  157. #define TCHAR char  
  158. #endif  
  159. #ifndef _T  
  160. #define _T(__x) (__x)  
  161. #define _tmain main  
  162. #define _tprintf printf  
  163. #define _getts gets  
  164. #define _tcslen strlen  
  165. #define _tfopen fopen  
  166. #define _tcscpy strcpy  
  167. #define _tcscat strcat  
  168. #define _sntprintf snprintf  
  169. #endif  
  170. #endif  
  171. #endif  
  172.   
  173. ///  
  174. // Define variable types  
  175.   
  176. #ifndef UINT_8  
  177. #ifdef _MSC_VER // Compiling with Microsoft compiler  
  178. #define UINT_8 unsigned __int8  
  179. #else // !_MSC_VER  
  180. #define UINT_8 unsigned char  
  181. #endif // _MSC_VER  
  182. #endif  
  183.   
  184. #ifndef UINT_32  
  185. #ifdef _MSC_VER // Compiling with Microsoft compiler  
  186. #define UINT_32 unsigned __int32  
  187. #else // !_MSC_VER  
  188. #if (ULONG_MAX == 0xFFFFFFFFUL)  
  189. #define UINT_32 unsigned long  
  190. #else  
  191. #define UINT_32 unsigned int  
  192. #endif  
  193. #endif // _MSC_VER  
  194. #endif // UINT_32  
  195.   
  196. #ifndef INT_64  
  197. #ifdef _MSC_VER // Compiling with Microsoft compiler  
  198. #define INT_64 __int64  
  199. #else // !_MSC_VER  
  200. #define INT_64 long long  
  201. #endif // _MSC_VER  
  202. #endif // INT_64  
  203.   
  204. #ifndef UINT_64  
  205. #ifdef _MSC_VER // Compiling with Microsoft compiler  
  206. #define UINT_64 unsigned __int64  
  207. #else // !_MSC_VER  
  208. #define UINT_64 unsigned long long  
  209. #endif // _MSC_VER  
  210. #endif // UINT_64  
  211.   
  212. ///  
  213. // Declare SHA-1 workspace  
  214.   
  215. typedef union  
  216. {  
  217.     UINT_8 c[64];  
  218.     UINT_32 l[16];  
  219. } SHA1_WORKSPACE_BLOCK;  
  220.   
  221. class CSHA1  
  222. {  
  223. public:  
  224. #ifdef SHA1_UTILITY_FUNCTIONS  
  225.     // Different formats for ReportHash(Stl)  
  226.     enum REPORT_TYPE  
  227.     {  
  228.         REPORT_HEX = 0,  
  229.         REPORT_DIGIT = 1,  
  230.         REPORT_HEX_SHORT = 2  
  231.     };  
  232. #endif  
  233.   
  234.     // Constructor and destructor  
  235.     CSHA1();  
  236.   
  237. #ifdef SHA1_WIPE_VARIABLES  
  238.     ~CSHA1();  
  239. #endif  
  240.   
  241.     void Reset();  
  242.   
  243.     // Hash in binary data and strings  
  244.     void Update(const UINT_8* pbData, UINT_32 uLen);  
  245.   
  246. #ifdef SHA1_UTILITY_FUNCTIONS  
  247.     // Hash in file contents  
  248.     bool HashFile(const TCHAR* tszFileName);  
  249. #endif  
  250.   
  251.     // Finalize hash; call it before using ReportHash(Stl)  
  252.     void Final();  
  253.   
  254. #ifdef SHA1_UTILITY_FUNCTIONS  
  255.     bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const;  
  256. #endif  
  257.   
  258. #ifdef SHA1_STL_FUNCTIONS  
  259.     bool ReportHashStl(std::basic_string<TCHAR>& strOut, REPORT_TYPE rtReportType =  
  260.         REPORT_HEX) const;  
  261. #endif  
  262.   
  263.     // Get the raw message digest (20 bytes)  
  264.     bool GetHash(UINT_8* pbDest20) const;  
  265.   
  266. private:  
  267.     // Private SHA-1 transformation  
  268.     void Transform(UINT_32* pState, const UINT_8* pBuffer);  
  269.   
  270.     // Member variables  
  271.     UINT_32 m_state[5];  
  272.     UINT_32 m_count[2];  
  273.     UINT_32 m_reserved0[1]; // Memory alignment padding  
  274.     UINT_8 m_buffer[64];  
  275.     UINT_8 m_digest[20];  
  276.     UINT_32 m_reserved1[3]; // Memory alignment padding  
  277.   
  278.     UINT_8 m_workspace[64];  
  279.     SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above  
  280. };  
  281.   
  282. #endif // SHA1_H_A545E61D43E9404E8D736869AB3CBFE7  


SHA1.cpp

[cpp]  view plain  copy
  1. /* 
  2.   100% free public domain implementation of the SHA-1 algorithm 
  3.   by Dominik Reichl <dominik.reichl@t-online.de> 
  4.   Web: http://www.dominik-reichl.de/ 
  5.  
  6.   See header file for version history and test vectors. 
  7. */  
  8.   
  9. // If compiling with MFC, you might want to add #include "StdAfx.h"  
  10.   
  11. #define _CRT_SECURE_NO_WARNINGS  
  12. #include "SHA1.h"  
  13.   
  14. #define SHA1_MAX_FILE_BUFFER (32 * 20 * 820)  
  15.   
  16. // Rotate p_val32 by p_nBits bits to the left  
  17. #ifndef ROL32  
  18. #ifdef _MSC_VER  
  19. #define ROL32(p_val32,p_nBits) _rotl(p_val32,p_nBits)  
  20. #else  
  21. #define ROL32(p_val32,p_nBits) (((p_val32)<<(p_nBits))|((p_val32)>>(32-(p_nBits))))  
  22. #endif  
  23. #endif  
  24.   
  25. #ifdef SHA1_LITTLE_ENDIAN  
  26. #define SHABLK0(i) (m_block->l[i] = \  
  27.     (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))  
  28. #else  
  29. #define SHABLK0(i) (m_block->l[i])  
  30. #endif  
  31.   
  32. #define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ \  
  33.     m_block->l[(i+8)&15] ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))  
  34.   
  35. // SHA-1 rounds  
  36. #define S_R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);}  
  37. #define S_R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);}  
  38. #define S_R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,30);}  
  39. #define S_R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w=ROL32(w,30);}  
  40. #define S_R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,30);}  
  41.   
  42. #pragma warning(push)  
  43. // Disable compiler warning 'Conditional expression is constant'  
  44. #pragma warning(disable: 4127)  
  45.   
  46. CSHA1::CSHA1()  
  47. {  
  48.     m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace;  
  49.   
  50.     Reset();  
  51. }  
  52.   
  53. #ifdef SHA1_WIPE_VARIABLES  
  54. CSHA1::~CSHA1()  
  55. {  
  56.     Reset();  
  57. }  
  58. #endif  
  59.   
  60. void CSHA1::Reset()  
  61. {  
  62.     // SHA1 initialization constants  
  63.     m_state[0] = 0x67452301;  
  64.     m_state[1] = 0xEFCDAB89;  
  65.     m_state[2] = 0x98BADCFE;  
  66.     m_state[3] = 0x10325476;  
  67.     m_state[4] = 0xC3D2E1F0;  
  68.   
  69.     m_count[0] = 0;  
  70.     m_count[1] = 0;  
  71. }  
  72.   
  73. void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer)  
  74. {  
  75.     UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState[4];  
  76.   
  77.     memcpy(m_block, pBuffer, 64);  
  78.   
  79.     // 4 rounds of 20 operations each, loop unrolled  
  80.     S_R0(a,b,c,d,e, 0); S_R0(e,a,b,c,d, 1); S_R0(d,e,a,b,c, 2); S_R0(c,d,e,a,b, 3);  
  81.     S_R0(b,c,d,e,a, 4); S_R0(a,b,c,d,e, 5); S_R0(e,a,b,c,d, 6); S_R0(d,e,a,b,c, 7);  
  82.     S_R0(c,d,e,a,b, 8); S_R0(b,c,d,e,a, 9); S_R0(a,b,c,d,e,10); S_R0(e,a,b,c,d,11);  
  83.     S_R0(d,e,a,b,c,12); S_R0(c,d,e,a,b,13); S_R0(b,c,d,e,a,14); S_R0(a,b,c,d,e,15);  
  84.     S_R1(e,a,b,c,d,16); S_R1(d,e,a,b,c,17); S_R1(c,d,e,a,b,18); S_R1(b,c,d,e,a,19);  
  85.     S_R2(a,b,c,d,e,20); S_R2(e,a,b,c,d,21); S_R2(d,e,a,b,c,22); S_R2(c,d,e,a,b,23);  
  86.     S_R2(b,c,d,e,a,24); S_R2(a,b,c,d,e,25); S_R2(e,a,b,c,d,26); S_R2(d,e,a,b,c,27);  
  87.     S_R2(c,d,e,a,b,28); S_R2(b,c,d,e,a,29); S_R2(a,b,c,d,e,30); S_R2(e,a,b,c,d,31);  
  88.     S_R2(d,e,a,b,c,32); S_R2(c,d,e,a,b,33); S_R2(b,c,d,e,a,34); S_R2(a,b,c,d,e,35);  
  89.     S_R2(e,a,b,c,d,36); S_R2(d,e,a,b,c,37); S_R2(c,d,e,a,b,38); S_R2(b,c,d,e,a,39);  
  90.     S_R3(a,b,c,d,e,40); S_R3(e,a,b,c,d,41); S_R3(d,e,a,b,c,42); S_R3(c,d,e,a,b,43);  
  91.     S_R3(b,c,d,e,a,44); S_R3(a,b,c,d,e,45); S_R3(e,a,b,c,d,46); S_R3(d,e,a,b,c,47);  
  92.     S_R3(c,d,e,a,b,48); S_R3(b,c,d,e,a,49); S_R3(a,b,c,d,e,50); S_R3(e,a,b,c,d,51);  
  93.     S_R3(d,e,a,b,c,52); S_R3(c,d,e,a,b,53); S_R3(b,c,d,e,a,54); S_R3(a,b,c,d,e,55);  
  94.     S_R3(e,a,b,c,d,56); S_R3(d,e,a,b,c,57); S_R3(c,d,e,a,b,58); S_R3(b,c,d,e,a,59);  
  95.     S_R4(a,b,c,d,e,60); S_R4(e,a,b,c,d,61); S_R4(d,e,a,b,c,62); S_R4(c,d,e,a,b,63);  
  96.     S_R4(b,c,d,e,a,64); S_R4(a,b,c,d,e,65); S_R4(e,a,b,c,d,66); S_R4(d,e,a,b,c,67);  
  97.     S_R4(c,d,e,a,b,68); S_R4(b,c,d,e,a,69); S_R4(a,b,c,d,e,70); S_R4(e,a,b,c,d,71);  
  98.     S_R4(d,e,a,b,c,72); S_R4(c,d,e,a,b,73); S_R4(b,c,d,e,a,74); S_R4(a,b,c,d,e,75);  
  99.     S_R4(e,a,b,c,d,76); S_R4(d,e,a,b,c,77); S_R4(c,d,e,a,b,78); S_R4(b,c,d,e,a,79);  
  100.   
  101.     // Add the working vars back into state  
  102.     pState[0] += a;  
  103.     pState[1] += b;  
  104.     pState[2] += c;  
  105.     pState[3] += d;  
  106.     pState[4] += e;  
  107.   
  108.     // Wipe variables  
  109. #ifdef SHA1_WIPE_VARIABLES  
  110.     a = b = c = d = e = 0;  
  111. #endif  
  112. }  
  113.   
  114. void CSHA1::Update(const UINT_8* pbData, UINT_32 uLen)  
  115. {  
  116.     UINT_32 j = ((m_count[0] >> 3) & 0x3F);  
  117.   
  118.     if((m_count[0] += (uLen << 3)) < (uLen << 3))  
  119.         ++m_count[1]; // Overflow  
  120.   
  121.     m_count[1] += (uLen >> 29);  
  122.   
  123.     UINT_32 i;  
  124.     if((j + uLen) > 63)  
  125.     {  
  126.         i = 64 - j;  
  127.         memcpy(&m_buffer[j], pbData, i);  
  128.         Transform(m_state, m_buffer);  
  129.   
  130.         for( ; (i + 63) < uLen; i += 64)  
  131.             Transform(m_state, &pbData[i]);  
  132.   
  133.         j = 0;  
  134.     }  
  135.     else i = 0;  
  136.   
  137.     if((uLen - i) != 0)  
  138.         memcpy(&m_buffer[j], &pbData[i], uLen - i);  
  139. }  
  140.   
  141. #ifdef SHA1_UTILITY_FUNCTIONS  
  142. bool CSHA1::HashFile(const TCHAR* tszFileName)  
  143. {  
  144.     if(tszFileName == NULL) return false;  
  145.   
  146.     FILE* fpIn = _tfopen(tszFileName, _T("rb"));  
  147.     if(fpIn == NULL) return false;  
  148.   
  149.     UINT_8* pbData = new UINT_8[SHA1_MAX_FILE_BUFFER];  
  150.     if(pbData == NULL) { fclose(fpIn); return false; }  
  151.   
  152.     bool bSuccess = true;  
  153.     while(true)  
  154.     {  
  155.         const size_t uRead = fread(pbData, 1, SHA1_MAX_FILE_BUFFER, fpIn);  
  156.   
  157.         if(uRead > 0)  
  158.             Update(pbData, static_cast<UINT_32>(uRead));  
  159.   
  160.         if(uRead < SHA1_MAX_FILE_BUFFER)  
  161.         {  
  162.             if(feof(fpIn) == 0) bSuccess = false;  
  163.             break;  
  164.         }  
  165.     }  
  166.   
  167.     fclose(fpIn);  
  168.     delete[] pbData;  
  169.     return bSuccess;  
  170. }  
  171. #endif  
  172.   
  173. void CSHA1::Final()  
  174. {  
  175.     UINT_32 i;  
  176.   
  177.     UINT_8 pbFinalCount[8];  
  178.     for(i = 0; i < 8; ++i)  
  179.         pbFinalCount[i] = static_cast<UINT_8>((m_count[((i >= 4) ? 0 : 1)] >>  
  180.             ((3 - (i & 3)) * 8) ) & 0xFF); // Endian independent  
  181.   
  182.     Update((UINT_8*)"\200", 1);  
  183.   
  184.     while((m_count[0] & 504) != 448)  
  185.         Update((UINT_8*)"\0", 1);  
  186.   
  187.     Update(pbFinalCount, 8); // Cause a Transform()  
  188.   
  189.     for(i = 0; i < 20; ++i)  
  190.         m_digest[i] = static_cast<UINT_8>((m_state[i >> 2] >> ((3 -  
  191.             (i & 3)) * 8)) & 0xFF);  
  192.   
  193.     // Wipe variables for security reasons  
  194. #ifdef SHA1_WIPE_VARIABLES  
  195.     memset(m_buffer, 0, 64);  
  196.     memset(m_state, 0, 20);  
  197.     memset(m_count, 0, 8);  
  198.     memset(pbFinalCount, 0, 8);  
  199.     Transform(m_state, m_buffer);  
  200. #endif  
  201. }  
  202.   
  203. #ifdef SHA1_UTILITY_FUNCTIONS  
  204. bool CSHA1::ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType) const  
  205. {  
  206.     if(tszReport == NULL) return false;  
  207.   
  208.     TCHAR tszTemp[16];  
  209.   
  210.     if((rtReportType == REPORT_HEX) || (rtReportType == REPORT_HEX_SHORT))  
  211.     {  
  212.         _sntprintf(tszTemp, 15, _T("%02X"), m_digest[0]);  
  213.         _tcscpy(tszReport, tszTemp);  
  214.   
  215.         const TCHAR* lpFmt = ((rtReportType == REPORT_HEX) ? _T(" %02X") : _T("%02X"));  
  216.         for(size_t i = 1; i < 20; ++i)  
  217.         {  
  218.             _sntprintf(tszTemp, 15, lpFmt, m_digest[i]);  
  219.             _tcscat(tszReport, tszTemp);  
  220.         }  
  221.     }  
  222.     else if(rtReportType == REPORT_DIGIT)  
  223.     {  
  224.         _sntprintf(tszTemp, 15, _T("%u"), m_digest[0]);  
  225.         _tcscpy(tszReport, tszTemp);  
  226.   
  227.         for(size_t i = 1; i < 20; ++i)  
  228.         {  
  229.             _sntprintf(tszTemp, 15, _T(" %u"), m_digest[i]);  
  230.             _tcscat(tszReport, tszTemp);  
  231.         }  
  232.     }  
  233.     else return false;  
  234.   
  235.     return true;  
  236. }  
  237. #endif  
  238.   
  239. #ifdef SHA1_STL_FUNCTIONS  
  240. bool CSHA1::ReportHashStl(std::basic_string<TCHAR>& strOut, REPORT_TYPE rtReportType) const  
  241. {  
  242.     TCHAR tszOut[84];  
  243.     const bool bResult = ReportHash(tszOut, rtReportType);  
  244.     if(bResult) strOut = tszOut;  
  245.     return bResult;  
  246. }  
  247. #endif  
  248.   
  249. bool CSHA1::GetHash(UINT_8* pbDest20) const  
  250. {  
  251.     if(pbDest20 == NULL) return false;  
  252.     memcpy(pbDest20, m_digest, 20);  
  253.     return true;  
  254. }  
  255.   
  256. #pragma warning(pop)  

SHA1算法的基本使用:

[cpp]  view plain  copy
  1. CSHA1 sha1;  
  2. char str1[] = "123456";  
  3. char str2[] = "456789abcd";  
  4. sha1.Update((unsigned char*)str1,strlen(str1);  
  5. sha1.Update((unsigned char*)str2, strlen(str2);  
  6. sha1.Final();  
  7. unsigned char chSha1[20] = "";  
  8. sha1.GetHash(chSha1);  


此文中算法的部分代码参考自网络。

SHA1算法参考:http://www.dominik-reichl.de/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值