HASH算法,sha系列的基本写完

sha1 ,见我之前的一篇博客 http://andydhu.blog.51cto.com/3337368/824735

sha256

 
  
  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<time.h> 
  4. //#define DEBUG 1 
  5. #define RoundNum 64 
  6. #define BlockWidthNum 16 
  7. #define ConstNum 8 
  8. unsigned int H[ConstNum] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; 
  9. unsigned int K[RoundNum] = { 
  10. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 
  11. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
  12. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 
  13. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 
  14. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 
  15. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 
  16. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 
  17. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; 
  18.  
  19. unsigned int M[BlockWidthNum]; 
  20. unsigned int W[RoundNum]; 
  21. unsigned char LastString[BlockWidthNum*4*2]; 
  22. FILE * fp; 
  23. fpos_t pos; //文件长度 
  24. int flag ;  
  25. int LastRoundCount; 
  26.  
  27. int GetMessage(unsigned long long rLen); 
  28. void SetW(); 
  29. void Round(); 
  30. unsigned int ShiftNum3(unsigned int input, int OpOne, int OpTwo, int Opthree); 
  31.  
  32. int main(int argc, char *argv[]) 
  33. //  fp = fopen(argv[1],"rb"); 
  34.     if(!(fp = fopen(argv[1],"rb"))) 
  35.     { 
  36.         exit(1); 
  37.     } 
  38.     clock_t start, finish;   
  39.     start = clock();   
  40.      
  41.     fseek(fp, 0, SEEK_END); 
  42.     fgetpos(fp, &pos); 
  43.  
  44.     unsigned long long realLen = pos; 
  45.  
  46.     memset(LastString,0x00,strlen(LastString)*sizeof(unsigned char)); 
  47.      
  48.     int LastOut = realLen%(BlockWidthNum*4); 
  49.     fseek(fp,-1*LastOut,SEEK_END); 
  50.  
  51.     int i; 
  52.     fread(LastString,LastOut,1,fp); 
  53.     LastString[LastOut] = 0x80;  
  54.      
  55.     LastRoundCount = 1; 
  56.     flag = 0; 
  57.  
  58.     if( LastOut <= BlockWidthNum*4-1-8) 
  59.     { 
  60.         flag = 1; 
  61.     //  memcpy(LastString+512/8-8,&copyLen,8); 
  62.         for( i = 8; i >= 1; i--) 
  63.             LastString[512/8 - i] = (char)((realLen<<3)>>((i-1)*8));  
  64.     } 
  65.     else 
  66.     { 
  67.         flag = 2; 
  68.     //  memcpy(LastString+512/8*2-8,&copyLen,8); 
  69.         for( i = 1; i <= 8; i++) 
  70.             LastString[512/8*2 - i] = (char)((realLen<<3)>>((i-1)*8));  
  71.     } 
  72.  
  73.     realLen -= LastOut; 
  74.  
  75.     fseek(fp,0,SEEK_SET); 
  76.      
  77.     while(GetMessage(realLen)) 
  78.     { 
  79.         SetW(); 
  80.         Round(); 
  81.     } 
  82.      
  83.     printf("SHA256:  "); 
  84.     for(i = 0 ; i < ConstNum; i++) 
  85.         printf("%08x",H[i]); 
  86.     printf("\n");  
  87.      
  88.     finish = clock();   
  89.     double duration = (double)(finish - start) / CLOCKS_PER_SEC;  
  90.     printf("Cal time: %f seconds\n",duration); 
  91.     fclose(fp); 
  92.     return 0; 
  93.  
  94. int GetMessage(unsigned long long rLen) 
  95.     fgetpos(fp, &pos); 
  96.  
  97.     unsigned char temp[4]; 
  98.     if(pos + 16*4 <= rLen ) 
  99.     { 
  100.          
  101.         fread(M,4,16,fp); 
  102.         return 1; 
  103.     } 
  104.     if(LastRoundCount <= flag) 
  105.     { 
  106.         memcpy(M,(LastString+512/8*(LastRoundCount - 1)),64);//最后的一段或是两段 
  107.         LastRoundCount++; 
  108.         return 1; 
  109.     } 
  110.     else 
  111.         return 0; //false;   
  112. void SetW() 
  113.     int index = 0; 
  114. //  memcpy(W,M,16*4); 
  115.  
  116.     for(index = 0; index <= 15;index++) 
  117.     { 
  118.         W[index] = (M[index]>>24)|(M[index]<<24)|((M[index]&0x00ff0000)>>8)|((M[index]&0x0000ff00)<<8); 
  119.     }  
  120.     unsigned int s0 = 0, s1 = 0; 
  121.     for(index = 16; index < RoundNum; index++) 
  122.     { 
  123.         s0 = 0; 
  124.         s1 = 0; 
  125.         s0 = ShiftNum3(W[index-2],17,19,-10); 
  126.         s1 = ShiftNum3(W[index-15],7,18,-3); 
  127.         W[index] = (s0 + W[index-7] + s1 + W[index-16]); 
  128. //      printf(" %08x ", W[index]); 
  129.     } 
  130.  
  131. unsigned int ShiftNum3(unsigned int input, int OpOne, int OpTwo, int Opthree) 
  132.     unsigned int Ans = 0 ;  
  133.     Ans ^= ((input >> OpOne)|(input<<(32-OpOne))); 
  134.     Ans ^= ((input >> OpTwo)|(input<<(32-OpTwo))); 
  135.     if(Opthree > 0) 
  136.         Ans ^= ((input >> Opthree)|(input<<(32-Opthree))); 
  137.     else 
  138.     { 
  139.     //  printf("%d",Opthree); 
  140.         Opthree = 0 - Opthree; 
  141.     //  printf("%d",Opthree); 
  142.         Ans ^= (input >> Opthree); 
  143.     } 
  144.     return Ans; 
  145.  
  146. void Round() 
  147.     unsigned int A,B,C,D,E,F,G,I; 
  148.     A = H[0]; 
  149.     B = H[1]; 
  150.     C = H[2]; 
  151.     D = H[3]; 
  152.     E = H[4]; 
  153.     F = H[5]; 
  154.     G = H[6]; 
  155.     I = H[7]; 
  156.      
  157.     int index = 0; 
  158.     unsigned int t1 = 0, t2= 0, s0 = 0, s1 = 0; 
  159.     for(index = 0;index < RoundNum ;index++) 
  160.     { 
  161.         s0 = 0; 
  162.         s1 = 0; 
  163.         s0 = ShiftNum3(A, 2, 13, 22); 
  164.         t2 = s0 + ((A&B)^(A&C)^(B&C)); 
  165.         s1 = ShiftNum3(E, 6, 11, 25); 
  166.         t1 = I + s1 + ((E&F)^((~E)&G)) + K[index] + W[index]; 
  167.          
  168.         I = G; 
  169.         G = F; 
  170.         F = E; 
  171.         E = D + t1; 
  172.         D = C; 
  173.         C = B; 
  174.         B = A; 
  175.         A = t1 + t2; 
  176. #ifdef DEBUG 
  177.     printf("ABCDE  %x %x %x %x %x \n",A,B,C,D,E); 
  178.     system("pause"); 
  179. #endif 
  180.     } 
  181.  
  182.     H[0]+=A; 
  183.     H[1]+=B; 
  184.     H[2]+=C; 
  185.     H[3]+=D; 
  186.     H[4]+=E; 
  187.     H[5]+=F; 
  188.     H[6]+=G; 
  189.     H[7]+=I; 

sha384

 
  
  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<time.h> 
  4. //#define DEBUG 1 
  5. #define RoundNum 80 
  6. #define BlockWidthNum 16 
  7. #define ConstNum 8 
  8. unsigned long long H[ConstNum] = { 
  9. 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, 
  10. 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4}; 
  11. unsigned long long K[RoundNum] = { 
  12. 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,  
  13. 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,  
  14. 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,  
  15. 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,  
  16. 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,  
  17. 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,  
  18. 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,  
  19. 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,  
  20. 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,  
  21. 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,  
  22. 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,  
  23. 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,  
  24. 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,  
  25. 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,  
  26. 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,  
  27. 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,  
  28. 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,  
  29. 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,  
  30. 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,  
  31. 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817}; 
  32.  
  33. unsigned long long M[BlockWidthNum]; 
  34. unsigned long long W[RoundNum]; 
  35. unsigned char LastString[BlockWidthNum*8*2]; 
  36. FILE * fp; 
  37. fpos_t pos; //文件长度 
  38. int flag ;  
  39. int LastRoundCount; 
  40.  
  41. int GetMessage(unsigned long long rLen); 
  42. void SetW(); 
  43. void Round(); 
  44. unsigned long long ShiftNum3(unsigned long long input, int OpOne, int OpTwo, int Opthree); 
  45.  
  46. int main(int argc, char *argv[]) 
  47. //  fp = fopen(argv[1],"rb"); 
  48.     if(!(fp = fopen(argv[1],"rb"))) 
  49.     { 
  50.         exit(1); 
  51.     } 
  52.     clock_t start, finish;   
  53.     start = clock();   
  54.      
  55.     fseek(fp, 0, SEEK_END); 
  56.     fgetpos(fp, &pos); 
  57.  
  58.     unsigned long long realLen = pos;//暂时不支持hash超大文件 
  59.  
  60.     memset(LastString,0x00,strlen(LastString)*sizeof(unsigned char)); 
  61.      
  62.     int LastOut = realLen%(BlockWidthNum*8); 
  63.     fseek(fp,-1*LastOut,SEEK_END); 
  64.  
  65.     int i; 
  66.     fread(LastString,LastOut,1,fp); 
  67.     LastString[LastOut] = 0x80;  
  68.      
  69.     LastRoundCount = 1; 
  70.     flag = 0; 
  71. //暂时不支持hash大小超过2^64的文件, 
  72. //sha512更长了,这样更加安全了,但是也不一定要hash这种超大的文件 
  73.     if( LastOut <= BlockWidthNum*8-1-16) 
  74.     { 
  75.         flag = 1; 
  76.     //  memcpy(LastString+512/8-8,&copyLen,8); 
  77.         for( i = 8; i >= 1; i--) 
  78.             LastString[BlockWidthNum*8 - i] = (char)((realLen<<3)>>((i-1)*8));  
  79.     } 
  80.     else 
  81.     { 
  82.         flag = 2; 
  83.     //  memcpy(LastString+512/8*2-8,&copyLen,8); 
  84.         for( i = 1; i <= 8; i++) 
  85.             LastString[BlockWidthNum*8*2 - i] = (char)((realLen<<3)>>((i-1)*8));  
  86.     } 
  87.  
  88.     realLen -= LastOut; 
  89.  
  90.     fseek(fp,0,SEEK_SET); 
  91.      
  92.     while(GetMessage(realLen)) 
  93.     { 
  94.         SetW(); 
  95.         Round(); 
  96.     } 
  97.      
  98.     printf("SHA384:  "); 
  99.     for(i = 0 ; i < 6; i++) 
  100.         printf("%016llx",H[i]); 
  101.     printf("\n");  
  102.      
  103.     finish = clock();   
  104.     double duration = (double)(finish - start) / CLOCKS_PER_SEC;  
  105.     printf("Cal time: %f seconds\n",duration); 
  106.     fclose(fp); 
  107.     return 0; 
  108.  
  109. int GetMessage(unsigned long long rLen) 
  110.     fgetpos(fp, &pos); 
  111.  
  112.     if(pos + 16 * 8 <= rLen ) 
  113.     { 
  114.         fread(M,8,16,fp); 
  115.         return 1; 
  116.     } 
  117.     if(LastRoundCount <= flag) 
  118.     { 
  119.         memcpy(M,(LastString+BlockWidthNum*8*(LastRoundCount - 1)),BlockWidthNum*8);//最后的一段或是两段 
  120.         LastRoundCount++; 
  121.         return 1; 
  122.     } 
  123.     else 
  124.         return 0; //false;   
  125. void SetW() 
  126.     int index = 0; 
  127. //  memcpy(W,M,16*4); 
  128.  
  129.     for(index = 0; index <= 15;index++) 
  130.     { 
  131.         W[index] = (M[index]>>56)|(M[index]<<56)|((M[index]&0x00ff000000000000)>>40)|((M[index]&0x000000000000ff00)<<40) 
  132.                     |((M[index]&0x0000ff0000000000)>>24)|((M[index]&0x0000000000ff0000)<<24)|((M[index]&0x000000ff00000000)>>8)|((M[index]&0x00000000ff000000)<<8); 
  133. //      printf("%016llx ",W[index]); 
  134.     }  
  135.     unsigned long long s0 = 0, s1 = 0; 
  136.     for(index = 16; index < RoundNum; index++) 
  137.     { 
  138.         s0 = 0; 
  139.         s1 = 0; 
  140.         s0 = ShiftNum3(W[index-2],19,61,-6); 
  141.         s1 = ShiftNum3(W[index-15],1,8,-7); 
  142.         W[index] = (s0 + W[index-7] + s1 + W[index-16]); 
  143. //      printf("%016llx ",W[index]); 
  144.     } 
  145.  
  146. unsigned long long ShiftNum3(unsigned long long input, int OpOne, int OpTwo, int Opthree) 
  147.     unsigned long long Ans = 0 ;  
  148.     Ans ^= ((input >> OpOne)|(input<<(64-OpOne))); 
  149.     Ans ^= ((input >> OpTwo)|(input<<(64-OpTwo))); 
  150.     if(Opthree > 0) 
  151.         Ans ^= ((input >> Opthree)|(input<<(64-Opthree))); 
  152.     else 
  153.     { 
  154.     //  printf("%d",Opthree); 
  155.         Opthree = 0 - Opthree; 
  156.     //  printf("%d",Opthree); 
  157.         Ans ^= (input >> Opthree); 
  158.     } 
  159.     return Ans; 
  160.  
  161. void Round() 
  162.     unsigned long long A,B,C,D,E,F,G,I; 
  163.     A = H[0]; 
  164.     B = H[1]; 
  165.     C = H[2]; 
  166.     D = H[3]; 
  167.     E = H[4]; 
  168.     F = H[5]; 
  169.     G = H[6]; 
  170.     I = H[7]; 
  171.      
  172.     int index = 0; 
  173.     unsigned long long t1 = 0, t2= 0, s0 = 0, s1 = 0; 
  174.     for(index = 0;index < RoundNum ;index++) 
  175.     { 
  176.         s0 = 0; 
  177.         s1 = 0; 
  178.         s0 = ShiftNum3(A, 28, 34, 39); 
  179.         t2 = s0 + ((A&B)^(A&C)^(B&C)); 
  180.         s1 = ShiftNum3(E, 14, 18, 41); 
  181.         t1 = I + s1 + ((E&F)^((~E)&G)) + K[index] + W[index]; 
  182.          
  183.         I = G; 
  184.         G = F; 
  185.         F = E; 
  186.         E = D + t1; 
  187.         D = C; 
  188.         C = B; 
  189.         B = A; 
  190.         A = t1 + t2; 
  191. #ifdef DEBUG 
  192.     printf("ABCDE  %x %x %x %x %x \n",A,B,C,D,E); 
  193.     system("pause"); 
  194. #endif 
  195.     } 
  196.  
  197.     H[0]+=A; 
  198.     H[1]+=B; 
  199.     H[2]+=C; 
  200.     H[3]+=D; 
  201.     H[4]+=E; 
  202.     H[5]+=F; 
  203.     H[6]+=G; 
  204.     H[7]+=I; 

sha512

 
  
  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<time.h> 
  4. //#define DEBUG 1 
  5. #define RoundNum 80 
  6. #define BlockWidthNum 16 
  7. #define ConstNum 8 
  8. unsigned long long H[ConstNum] = { 
  9. 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,  
  10. 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179}; 
  11. unsigned long long K[RoundNum] = { 
  12. 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,  
  13. 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,  
  14. 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,  
  15. 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,  
  16. 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,  
  17. 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,  
  18. 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,  
  19. 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,  
  20. 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,  
  21. 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,  
  22. 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,  
  23. 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,  
  24. 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,  
  25. 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,  
  26. 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,  
  27. 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,  
  28. 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,  
  29. 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,  
  30. 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,  
  31. 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817}; 
  32.  
  33. unsigned long long M[BlockWidthNum]; 
  34. unsigned long long W[RoundNum]; 
  35. unsigned char LastString[BlockWidthNum*8*2]; 
  36. FILE * fp; 
  37. fpos_t pos; //文件长度 
  38. int flag ;  
  39. int LastRoundCount; 
  40.  
  41. int GetMessage(unsigned long long rLen); 
  42. void SetW(); 
  43. void Round(); 
  44. unsigned long long ShiftNum3(unsigned long long input, int OpOne, int OpTwo, int Opthree); 
  45.  
  46. int main(int argc, char *argv[]) 
  47. //  fp = fopen(argv[1],"rb"); 
  48.     if(!(fp = fopen(argv[1],"rb"))) 
  49.     { 
  50.         exit(1); 
  51.     } 
  52.     clock_t start, finish;   
  53.     start = clock();   
  54.      
  55.     fseek(fp, 0, SEEK_END); 
  56.     fgetpos(fp, &pos); 
  57.  
  58.     unsigned long long realLen = pos;//暂时不支持hash超大文件 
  59.  
  60.     memset(LastString,0x00,strlen(LastString)*sizeof(unsigned char)); 
  61.      
  62.     int LastOut = realLen%(BlockWidthNum*8); 
  63.     fseek(fp,-1*LastOut,SEEK_END); 
  64.  
  65.     int i; 
  66.     fread(LastString,LastOut,1,fp); 
  67.     LastString[LastOut] = 0x80;  
  68.      
  69.     LastRoundCount = 1; 
  70.     flag = 0; 
  71. //暂时不支持hash大小超过2^64的文件, 
  72. //sha512更长了,这样更加安全了,但是也不一定要hash这种超大的文件 
  73.     if( LastOut <= BlockWidthNum*8-1-16) 
  74.     { 
  75.         flag = 1; 
  76.     //  memcpy(LastString+512/8-8,&copyLen,8); 
  77.         for( i = 8; i >= 1; i--) 
  78.             LastString[BlockWidthNum*8 - i] = (char)((realLen<<3)>>((i-1)*8));  
  79.     } 
  80.     else 
  81.     { 
  82.         flag = 2; 
  83.     //  memcpy(LastString+512/8*2-8,&copyLen,8); 
  84.         for( i = 1; i <= 8; i++) 
  85.             LastString[BlockWidthNum*8*2 - i] = (char)((realLen<<3)>>((i-1)*8));  
  86.     } 
  87.  
  88.     realLen -= LastOut; 
  89.  
  90.     fseek(fp,0,SEEK_SET); 
  91.      
  92.     while(GetMessage(realLen)) 
  93.     { 
  94.         SetW(); 
  95.         Round(); 
  96.     } 
  97.      
  98.     printf("SHA512:  "); 
  99.     for(i = 0 ; i < ConstNum; i++) 
  100.         printf("%016llx",H[i]); 
  101.     printf("\n");  
  102.      
  103.     finish = clock();   
  104.     double duration = (double)(finish - start) / CLOCKS_PER_SEC;  
  105.     printf("Cal time: %f seconds\n",duration); 
  106.     fclose(fp); 
  107.     return 0; 
  108.  
  109. int GetMessage(unsigned long long rLen) 
  110.     fgetpos(fp, &pos); 
  111.  
  112.     if(pos + 16 * 8 <= rLen ) 
  113.     { 
  114.         fread(M,8,16,fp); 
  115.         return 1; 
  116.     } 
  117.     if(LastRoundCount <= flag) 
  118.     { 
  119.         memcpy(M,(LastString+BlockWidthNum*8*(LastRoundCount - 1)),BlockWidthNum*8);//最后的一段或是两段 
  120.         LastRoundCount++; 
  121.         return 1; 
  122.     } 
  123.     else 
  124.         return 0; //false;   
  125. void SetW() 
  126.     int index = 0; 
  127. //  memcpy(W,M,16*4); 
  128.  
  129.     for(index = 0; index <= 15;index++) 
  130.     { 
  131.         W[index] = (M[index]>>56)|(M[index]<<56)|((M[index]&0x00ff000000000000)>>40)|((M[index]&0x000000000000ff00)<<40) 
  132.                     |((M[index]&0x0000ff0000000000)>>24)|((M[index]&0x0000000000ff0000)<<24)|((M[index]&0x000000ff00000000)>>8)|((M[index]&0x00000000ff000000)<<8); 
  133. //      printf("%016llx ",W[index]); 
  134.     }  
  135.     unsigned long long s0 = 0, s1 = 0; 
  136.     for(index = 16; index < RoundNum; index++) 
  137.     { 
  138.         s0 = 0; 
  139.         s1 = 0; 
  140.         s0 = ShiftNum3(W[index-2],19,61,-6); 
  141.         s1 = ShiftNum3(W[index-15],1,8,-7); 
  142.         W[index] = (s0 + W[index-7] + s1 + W[index-16]); 
  143. //      printf("%016llx ",W[index]); 
  144.     } 
  145.  
  146. unsigned long long ShiftNum3(unsigned long long input, int OpOne, int OpTwo, int Opthree) 
  147.     unsigned long long Ans = 0 ;  
  148.     Ans ^= ((input >> OpOne)|(input<<(64-OpOne))); 
  149.     Ans ^= ((input >> OpTwo)|(input<<(64-OpTwo))); 
  150.     if(Opthree > 0) 
  151.         Ans ^= ((input >> Opthree)|(input<<(64-Opthree))); 
  152.     else 
  153.     { 
  154.     //  printf("%d",Opthree); 
  155.         Opthree = 0 - Opthree; 
  156.     //  printf("%d",Opthree); 
  157.         Ans ^= (input >> Opthree); 
  158.     } 
  159.     return Ans; 
  160.  
  161. void Round() 
  162.     unsigned long long A,B,C,D,E,F,G,I; 
  163.     A = H[0]; 
  164.     B = H[1]; 
  165.     C = H[2]; 
  166.     D = H[3]; 
  167.     E = H[4]; 
  168.     F = H[5]; 
  169.     G = H[6]; 
  170.     I = H[7]; 
  171.      
  172.     int index = 0; 
  173.     unsigned long long t1 = 0, t2= 0, s0 = 0, s1 = 0; 
  174.     for(index = 0;index < RoundNum ;index++) 
  175.     { 
  176.         s0 = 0; 
  177.         s1 = 0; 
  178.         s0 = ShiftNum3(A, 28, 34, 39); 
  179.         t2 = s0 + ((A&B)^(A&C)^(B&C)); 
  180.         s1 = ShiftNum3(E, 14, 18, 41); 
  181.         t1 = I + s1 + ((E&F)^((~E)&G)) + K[index] + W[index]; 
  182.          
  183.         I = G; 
  184.         G = F; 
  185.         F = E; 
  186.         E = D + t1; 
  187.         D = C; 
  188.         C = B; 
  189.         B = A; 
  190.         A = t1 + t2; 
  191. #ifdef DEBUG 
  192.     printf("ABCDE  %x %x %x %x %x \n",A,B,C,D,E); 
  193.     system("pause"); 
  194. #endif 
  195.     } 
  196.  
  197.     H[0]+=A; 
  198.     H[1]+=B; 
  199.     H[2]+=C; 
  200.     H[3]+=D; 
  201.     H[4]+=E; 
  202.     H[5]+=F; 
  203.     H[6]+=G; 
  204.     H[7]+=I;