金山速盤開発(三)

16387 ワード

今日は同僚に食事をごちそうします.ああ、好きではありません.
金山の開発という文書にはurlをbase 64符号化する部分もあるので、今日のコードはbase 64部分です.
ヘッダー・ファイル・コードは次のとおりです.
   
   
   
   
  1. #ifndef __BASE64__ 
  2. #define __BASE64__ 
  3. const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";  
  4. char* base64_encode(const char* data, int data_len);  
  5. char *base64_decode(const char* data, int data_len);  
  6. static char find_pos(char ch);  
  7. #endif 

コード実装:
   
   
   
   
  1. #include   
  2. #include  
  3. #include  
  4. #include  
  5. #include "base64.h" 
  6.  
  7. char *base64_encode(const char* data, int data_len)  
  8. {  
  9.     //int data_len = strlen(data);  
  10.     int prepare = 0;  
  11.     int ret_len;  
  12.     int temp = 0;  
  13.     char *ret = NULL;  
  14.     char *f = NULL;  
  15.     int tmp = 0;  
  16.     char changed[4];  
  17.     int i = 0;  
  18.     ret_len = data_len / 3;  
  19.     temp = data_len % 3;  
  20.     if (temp > 0)  
  21.     {  
  22.         ret_len += 1;  
  23.     }  
  24.     ret_len = ret_len*4 + 1;  
  25.     ret = (char *)malloc(ret_len);  
  26.        
  27.     if ( ret == NULL)  
  28.     {  
  29.         printf("No enough memory.
    "
    );  
  30.         exit(0);  
  31.     }  
  32.     memset(ret, 0, ret_len);  
  33.     f = ret;  
  34.     while (tmp 
  35.     {  
  36.         temp = 0;  
  37.         prepare = 0;  
  38.         memset(changed, '\0', 4);  
  39.         while (temp 
  40.         {  
  41.             //printf("tmp = %d
    ", tmp); 
     
  42.             if (tmp >= data_len)  
  43.             {  
  44.                 break;  
  45.             }  
  46.             prepare = ((prepare <
  47.             tmp++;  
  48.             temp++;  
  49.         }  
  50.         prepare = (prepare<
  51.         //printf("before for : temp = %d, prepare = %d
    ", temp, prepare); 
     
  52.         for (i = 0; i 
  53.         {  
  54.             if (temp 
  55.             {  
  56.                 changed[i] = 0x40;  
  57.             }  
  58.             else  
  59.             {  
  60.                 changed[i] = (prepare>>((3-i)*6)) & 0x3F;  
  61.             }  
  62.             *f = base[changed[i]];  
  63.             //printf("%.2X", changed[i]);  
  64.             f++;  
  65.         }  
  66.     }  
  67.     *f = '\0';  
  68.        
  69.     return ret;  
  70.        
  71. }  
  72. /* */  
  73. static char find_pos(char ch)    
  74. {  
  75.     char *ptr = (char*)strrchr(base, ch);//the last position (the only) in base[]  
  76.     return (ptr - base);  
  77. }  
  78. /* */  
  79. char *base64_decode(const char *data, int data_len)  
  80. {  
  81.     int ret_len = (data_len / 4) * 3;  
  82.     int equal_count = 0;  
  83.     char *ret = NULL;  
  84.     char *f = NULL;  
  85.     int tmp = 0;  
  86.     int temp = 0;  
  87.     char need[3];  
  88.     int prepare = 0;  
  89.     int i = 0;  
  90.     if (*(data + data_len - 1) == '=')  
  91.     {  
  92.         equal_count += 1;  
  93.     }  
  94.     if (*(data + data_len - 2) == '=')  
  95.     {  
  96.         equal_count += 1;  
  97.     }  
  98.     if (*(data + data_len - 3) == '=')  
  99.     {//seems impossible  
  100.         equal_count += 1;  
  101.     }  
  102.     switch (equal_count)  
  103.     {  
  104.     case 0:  
  105.         ret_len += 4;//3 + 1 [1 for NULL]  
  106.         break;  
  107.     case 1:  
  108.         ret_len += 4;//Ceil((6*3)/8)+1  
  109.         break;  
  110.     case 2:  
  111.         ret_len += 3;//Ceil((6*2)/8)+1  
  112.         break;  
  113.     case 3:  
  114.         ret_len += 2;//Ceil((6*1)/8)+1  
  115.         break;  
  116.     }  
  117.     ret = (char *)malloc(ret_len);  
  118.     if (ret == NULL)  
  119.     {  
  120.         printf("No enough memory.
    "
    );  
  121.         exit(0);  
  122.     }  
  123.     memset(ret, 0, ret_len);  
  124.     f = ret;  
  125.     while (tmp 
  126.     {  
  127.         temp = 0;  
  128.         prepare = 0;  
  129.         memset(need, 0, 4);  
  130.         while (temp 
  131.         {  
  132.             if (tmp >= (data_len - equal_count))  
  133.             {  
  134.                 break;  
  135.             }  
  136.             prepare = (prepare <
  137.             temp++;  
  138.             tmp++;  
  139.         }  
  140.         prepare = prepare <
  141.         for (i=0; i<3 ;i++ )  
  142.         {  
  143.             if (i == temp)  
  144.             {  
  145.                 break;  
  146.             }  
  147.             *f = (char)((prepare>>((2-i)*8)) & 0xFF);  
  148.             f++;  
  149.         }  
  150.     }  
  151.     *f = '\0';  
  152.     return ret;  
  153. }  

上のコードはbase 64の符号化問題を解決し、添付ファイルはコードファイルである.