Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279959
  • 博文数量: 38
  • 博客积分: 706
  • 博客等级: 上士
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-05 09:09
文章分类

全部博文(38)

文章存档

2013年(23)

2012年(15)

我的朋友

分类: C/C++

2013-05-15 15:36:49

具体代码如下:

点击(此处)折叠或打开

  1. include <stdio.h>
  2. const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  3. char* base64_encode(const char* data, int data_len);
  4. char *base64_decode(const char* data, int data_len);
  5. static char find_pos(char ch);
  6. int main(int argc, char* argv[])
  7. {
  8.     char *t = "那个abcd你好吗,哈哈,ANMOL";
  9.     int i = 0;
  10.     int j = strlen(t);
  11.     char *enc = base64_encode(t, j);
  12.     int len = strlen(enc);
  13.     char *dec = base64_decode(enc, len);
  14.     printf("noriginal: %sn", t);
  15.     printf("nencoded : %sn", enc);
  16.     printf("ndecoded : %sn", dec);
  17.     free(enc);
  18.     free(dec);
  19.     return 0;
  20. }
  21. /* */
  22. char *base64_encode(const char* data, int data_len)
  23. {
  24.     //int data_len = strlen(data);
  25.     int prepare = 0;
  26.     int ret_len;
  27.     int temp = 0;
  28.     char *ret = NULL;
  29.     char *f = NULL;
  30.     int tmp = 0;
  31.     char changed[4];
  32.     int i = 0;
  33.     ret_len = data_len / 3;
  34.     temp = data_len % 3;
  35.     if (temp > 0)
  36.     {
  37.         ret_len += 1;
  38.     }
  39.     ret_len = ret_len*4 + 1;
  40.     ret = (char *)malloc(ret_len);
  41.       
  42.     if ( ret == NULL)
  43.     {
  44.         printf("No enough memory.n");
  45.         exit(0);
  46.     }
  47.     memset(ret, 0, ret_len);
  48.     f = ret;
  49.     while (tmp < data_len)
  50.     {
  51.         temp = 0;
  52.         prepare = 0;
  53.         memset(changed, '0', 4);
  54.         while (temp < 3)
  55.         {
  56.             //printf("tmp = %dn", tmp);
  57.             if (tmp >= data_len)
  58.             {
  59.                 break;
  60.             }
  61.             prepare = ((prepare << 8) | (data[tmp] & 0xFF));
  62.             tmp++;
  63.             temp++;
  64.         }
  65.         prepare = (prepare<<((3-temp)*8));
  66.         //printf("before for : temp = %d, prepare = %dn", temp, prepare);
  67.         for (i = 0; i < 4 ;i++ )
  68.         {
  69.             if (temp < i)
  70.             {
  71.                 changed[i] = 0x40;
  72.             }
  73.             else
  74.             {
  75.                 changed[i] = (prepare>>((3-i)*6)) & 0x3F;
  76.             }
  77.             *f = base[changed[i]];
  78.             //printf("%.2X", changed[i]);
  79.             f++;
  80.         }
  81.     }
  82.     *f = '0';
  83.       
  84.     return ret;
  85.       
  86. }
  87. /* */
  88. static char find_pos(char ch)
  89. {
  90.     char *ptr = (char*)strrchr(base, ch);//the last position (the only) in base[]
  91.     return (ptr - base);
  92. }
  93. /* */
  94. char *base64_decode(const char *data, int data_len)
  95. {
  96.     int ret_len = (data_len / 4) * 3;
  97.     int equal_count = 0;
  98.     char *ret = NULL;
  99.     char *f = NULL;
  100.     int tmp = 0;
  101.     int temp = 0;
  102.     char need[3];
  103.     int prepare = 0;
  104.     int i = 0;
  105.     if (*(data + data_len - 1) == '=')
  106.     {
  107.         equal_count += 1;
  108.     }
  109.     if (*(data + data_len - 2) == '=')
  110.     {
  111.         equal_count += 1;
  112.     }
  113.     if (*(data + data_len - 3) == '=')
  114.     {//seems impossible
  115.         equal_count += 1;
  116.     }
  117.     switch (equal_count)
  118.     {
  119.     case 0:
  120.         ret_len += 4;//3 + 1 [1 for NULL]
  121.         break;
  122.     case 1:
  123.         ret_len += 4;//Ceil((6*3)/8)+1
  124.         break;
  125.     case 2:
  126.         ret_len += 3;//Ceil((6*2)/8)+1
  127.         break;
  128.     case 3:
  129.         ret_len += 2;//Ceil((6*1)/8)+1
  130.         break;
  131.     }
  132.     ret = (char *)malloc(ret_len);
  133.     if (ret == NULL)
  134.     {
  135.         printf("No enough memory.n");
  136.         exit(0);
  137.     }
  138.     memset(ret, 0, ret_len);
  139.     f = ret;
  140.     while (tmp < (data_len - equal_count))
  141.     {
  142.         temp = 0;
  143.         prepare = 0;
  144.         memset(need, 0, 4);
  145.         while (temp < 4)
  146.         {
  147.             if (tmp >= (data_len - equal_count))
  148.             {
  149.                 break;
  150.             }
  151.             prepare = (prepare << 6) | (find_pos(data[tmp]));
  152.             temp++;
  153.             tmp++;
  154.         }
  155.         prepare = prepare << ((4-temp) * 6);
  156.         for (i=0; i<3 ;i++ )
  157.         {
  158.             if (i == temp)
  159.             {
  160.                 break;
  161.             }
  162.             *f = (char)((prepare>>((2-i)*8)) & 0xFF);
  163.             f++;
  164.         }
  165.     }
  166.     *f = '0';
  167.     return ret;
  168. }
这里添加了两个方法find_pos和base64_decode。前者是寻找给定字符在base数组中的位置的,使用了strrchr函数,寻找字符在字符串中最后一次的位置,由于总会存在并且仅存在一次,所以函数结果直接使用。base64_decode函数里边跟encode函数差不多,我没有作注释。

对于代码中给定的串,运行结果如下:

original: 那个abcd你好吗,哈哈,ANMOL

encoded : xMe49mFiY2TE47rDwvCjrLn+uf6jrEFOTU9M
decoded : 那个abcd你好吗,哈哈,ANMOL

阅读(2047) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~