今天呢,和同事们抱怨,我这段时间可憋苦了,今天说出来终于好多了,然后收获也挺多的,同事说“你既然不满意现状,那么为什么不去行动呢?” ,一下子就使我愣在当场了。对啊,我为什么抱怨啊,为什么我不行动。

                                                    --------今天是改变的日子

做事呢一定要做好,不情不愿的还不如不做,浪费时间,浪费感情,阻碍地球转动。

      昨天发了base64编码的代码,今天就贴出来算法的代码hmac-sha1的代码

  惯例,头文件:

   
   
   
   
  1. #ifndef __HMAC_SHA1__ 
  2. #define __HMAC_SHA1__ 
  3.  
  4. /* Function to compute the digest */ 
  5. char* hmac_sha( 
  6.     char* k, /* secret key */ 
  7.     int lk, /* length of the key in bytes */ 
  8.     char* d, /* data */ 
  9.     int ld, /* length of data in bytes */ 
  10.     char* out, /* output buffer, at least "t" bytes */ 
  11.     int t 
  12. ); 
  13.  
  14. #endif 

然后呢,就是实现:

 

   
   
   
   
  1. #include "sha1.h" 
  2. //#include "base64.h" 
  3.  
  4. #include  
  5. #include  
  6. #include  
  7.  
  8. #include  
  9.  
  10. #ifndef SHA_DIGESTSIZE 
  11. #define SHA_DIGESTSIZE 20 
  12. #endif 
  13.  
  14. #ifndef SHA_BLOCKSIZE 
  15. #define SHA_BLOCKSIZE 64 
  16. #endif 
  17.  
  18. extern char* base64_encode(const char* data, int data_len);  
  19. /* Hash a single 512-bit block. This is the core of the algorithm. */ 
  20.  
  21. void SHA1Transform(__u32 state[5], __u8 buffer[64]) 
  22. __u32 a, b, c, d, e; 
  23. typedef union { 
  24.     unsigned char c[64]; 
  25.     __u32 l[16]; 
  26. } CHAR64LONG16; 
  27.  
  28. CHAR64LONG16* block; 
  29.  
  30. #ifdef SHA1HANDSOFF 
  31.  
  32. static unsigned char workspace[64]; 
  33.     block = (CHAR64LONG16*)workspace; 
  34. //    NdisMoveMemory(block, buffer, 64); 
  35.     memcpy(block, buffer, 64); 
  36. #else 
  37.     block = (CHAR64LONG16*)buffer; 
  38. #endif 
  39.     /* Copy context->state[] to working vars */ 
  40.     a = state[0]; 
  41.     b = state[1]; 
  42.     c = state[2]; 
  43.     d = state[3]; 
  44.     e = state[4]; 
  45.     /* 4 rounds of 20 operations each. Loop unrolled. */ 
  46.     R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 
  47.     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 
  48.     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 
  49.     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 
  50.     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 
  51.     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 
  52.     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 
  53.     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 
  54.     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 
  55.     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 
  56.     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 
  57.     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 
  58.     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 
  59.     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 
  60.     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 
  61.     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 
  62.     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 
  63.     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 
  64.     R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 
  65.     R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 
  66.     /* Add the working vars back into context.state[] */ 
  67.     state[0] += a; 
  68.     state[1] += b; 
  69.     state[2] += c; 
  70.     state[3] += d; 
  71.     state[4] += e; 
  72.     /* Wipe variables */ 
  73.     a = b = c = d = e = 0; 
  74.  
  75.  
  76. /* SHA1Init - Initialize new context */ 
  77.  
  78. void SHA1Init(SHA1_CTX* context) 
  79.     /* SHA1 initialization constants */ 
  80.     context->state[0] = 0x67452301; 
  81.     context->state[1] = 0xEFCDAB89; 
  82.     context->state[2] = 0x98BADCFE; 
  83.     context->state[3] = 0x10325476; 
  84.     context->state[4] = 0xC3D2E1F0; 
  85.     context->count[0] = context->count[1] = 0; 
  86.  
  87.  
  88. /* Run your data through this. */ 
  89.  
  90. void SHA1Update(SHA1_CTX* context, unsigned char* data, __u32 len) 
  91.     __u32 i, j; 
  92.  
  93.     j = context->count[0]; 
  94.     if ((context->count[0] += len << 3) < j) 
  95.     context->count[1]++; 
  96.     context->count[1] += (len>>29); 
  97.     j = (j >> 3) & 63; 
  98.     if ((j + len) > 63) { 
  99. //        NdisMoveMemory(&context->buffer[j], data, (i = 64-j)); 
  100.         memcpy(&context->buffer[j], data, (i = 64-j)); 
  101.         SHA1Transform(context->state, context->buffer); 
  102.         for ( ; i + 63 < len; i += 64) { 
  103.             SHA1Transform(context->state, &data[i]); 
  104.         } 
  105.         j = 0; 
  106.     } 
  107.     else i = 0; 
  108. //    NdisMoveMemory(&context->buffer[j], &data[i], len - i); 
  109.     memcpy(&context->buffer[j], &data[i], len - i); 
  110.  
  111.  
  112. /* Add padding and return the message digest. */ 
  113.  
  114. void SHA1Final(unsigned char digest[20], SHA1_CTX* context) 
  115. __u32 i, j; 
  116. unsigned char finalcount[8]; 
  117.  
  118.     for (i = 0; i < 8; i++) { 
  119.         finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 
  120.          >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */ 
  121.     } 
  122.     SHA1Update(context, (unsigned char *)"\200", 1); 
  123.     while ((context->count[0] & 504) != 448) { 
  124.         SHA1Update(context, (unsigned char *)"\0", 1); 
  125.     } 
  126.     SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */ 
  127.     for (i = 0; i < 20; i++) { 
  128.         digest[i] = (unsigned char
  129.          ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 
  130.     } 
  131.     /* Wipe variables */ 
  132.     i = j = 0; 
  133. //    NdisZeroMemory(context->buffer, 64); 
  134. //    NdisZeroMemory(context->state, 20); 
  135. //    NdisZeroMemory(context->count, 8); 
  136. //    NdisZeroMemory(&finalcount, 8); 
  137.     memset(context->buffer, 0x00, 64); 
  138.     memset(context->state, 0x00, 20); 
  139.     memset(context->count, 0x00, 8); 
  140.     memset(&finalcount, 0x00, 8); 
  141.      
  142. #ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */ 
  143.     SHA1Transform(context->state, context->buffer); 
  144. #endif 
  145.  
  146.  
  147.  
  148. /* Function to print the digest */ 
  149. void pr_sha(FILE* fp, unsigned char* s, int t) 
  150.     int i ; 
  151.     /* 
  152.     for(i=0;i 
  153.         printf("%02x",s[i]);     
  154.     printf("\n"); 
  155.     */ 
  156.     printf("digest:%s\n",s); 
  157.     /* 
  158.     fprintf(fp, "0x") ; 
  159.     for (i = 0 ; i < t ; i++) 
  160.     { 
  161.         fprintf(fp, "%02x", s[i]) ; 
  162.         printf("\n"); 
  163.     } 
  164.     fprintf(fp, "0") ; 
  165.     */ 
  166.  
  167. void truncate_m 
  168.     char* d1, /* data to be truncate_md */ 
  169.     char* d2, /* truncate_md data */ 
  170.     int len /* length in bytes to keep */ 
  171.     int i ; 
  172.     for (i = 0 ; i < len ; i++) d2[i] = d1[i]; 
  173.  
  174. /* Function to compute the digest */ 
  175. char* hmac_sha 
  176.     char* k, /* secret key */ 
  177.     int lk, /* length of the key in bytes */ 
  178.     char* d, /* data */ 
  179.     int ld, /* length of data in bytes */ 
  180.     char* out, /* output buffer, at least "t" bytes */ 
  181.     int t 
  182.     SHA1_CTX ictx, octx ; 
  183.     char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE] ; 
  184.     char key[SHA_DIGESTSIZE] ; 
  185.     char buf[SHA_BLOCKSIZE] ; 
  186.     int i ; 
  187.  
  188.     if (lk > SHA_BLOCKSIZE) { 
  189.  
  190.     SHA1_CTX tctx ; 
  191.  
  192.     SHA1Init(&tctx) ; 
  193.     SHA1Update(&tctx, k, lk) ; 
  194.     SHA1Final(key, &tctx) ; 
  195.  
  196.     k = key ; 
  197.     lk = SHA_DIGESTSIZE ; 
  198.  
  199. /**** Inner Digest ****/ 
  200.  
  201.     SHA1Init(&ictx) ; 
  202.  
  203.     /* Pad the key for inner digest */ 
  204.     for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x36 ; 
  205.     for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x36 ; 
  206.  
  207.     SHA1Update(&ictx, buf, SHA_BLOCKSIZE) ; 
  208.     SHA1Update(&ictx, d, ld) ; 
  209.  
  210.     SHA1Final(isha, &ictx) ; 
  211.  
  212. /**** Outter Digest ****/ 
  213.  
  214.     SHA1Init(&octx) ; 
  215.  
  216. /* Pad the key for outter digest */ 
  217.  
  218.     for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x5C ; 
  219.     for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x5C ; 
  220.  
  221.     SHA1Update(&octx, buf, SHA_BLOCKSIZE) ; 
  222.     SHA1Update(&octx, isha, SHA_DIGESTSIZE) ; 
  223.  
  224.     SHA1Final(osha, &octx) ; 
  225.  
  226. /* truncate_m and print the results */ 
  227.     t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t ; 
  228.     truncate_m(osha, out, t) ; 
  229.     //pr_sha(stdout, out, t) ; 
  230.     return out; 
  231.     //printf("%s\n",base64_encode(out,t)); 
  232.  

好了,以上的代码都是进行测试过的,算法的问题现在没有时间进行研究。