免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 17883 | 回复: 26

[函数] C BASE64编解码函数 [复制链接]

论坛徽章:
0
发表于 2007-02-05 01:55 |显示全部楼层

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<unistd.h>
  4. #include<string.h>
  5. /**********************************************
  6. 作者:Minuit
  7. 时间:2007年02月05日 星期日  20时42分33秒
  8. 文件名:base64.c
  9. 描述:C base64编码操作函数
  10. **********************************************/
  11. /*
  12. A B C D E F G H I J  K  L  M  N  O  P  Q
  13. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  14. R   S  T  U  V  W  X  Y  Z  a  b  c  d  e  f  g  h
  15. 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
  16. i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y
  17. 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
  18. z  0  1  2  3  4  5  6  7  8  9  +  / (pad) =
  19. 51 52 53 54 55 56 57 58 59 60 61 62 63
  20. */
  21. static char base64_table[255];
  22. char *decode(const char*,char **);
  23. char *encode(const char*,char **);
  24. void base64_tableinit()
  25. {
  26.    int i,j;
  27.    bzero(base64_table,255);
  28.         for(j=0,i='A';i<='Z';i++) /*填base64编码表*/
  29.                 base64_table[i]=j++;
  30.         for(i='a';i<='z';i++)
  31.                 base64_table[i]=j++;
  32.         for(i='0';i<='9';i++)
  33.                 base64_table[i]=j++;
  34.         base64_table['+']=j++;
  35.         base64_table['/']=j++;
  36.         base64_table['=']=j;
  37. }
  38. char *decode(const char *cptr,char **rptr)
  39. {
  40.         char *res;
  41.         int clen,len;
  42.         static int init=0;
  43.         if(cptr==NULL)
  44.                 return NULL;
  45.         len=strlen(cptr);
  46.         if(len%4)  /*编了码的字符绝对是4的倍数*/
  47.                 return NULL;
  48.         if(!init)
  49.           {
  50.                 init=1;
  51.                 base64_tableinit();
  52.           }
  53.         clen=len/4;
  54.         if((res=malloc(len-clen))==NULL)
  55.                 return NULL;
  56.         for(*rptr=res;clen--;)
  57.           {
  58.                 *res=base64_table[*cptr++]<<2&0xfc;         /*cptr后六位移动到最高位*/
  59.                 *res++|=base64_table[*cptr]>>4;               /*跟着下个字符低两位给res低两位*/
  60.         *res=base64_table[*cptr++]<<4&0xf0;               /*填充res高四位其它清0*/
  61.                 *res++|=base64_table[*cptr]>>2&0x0f;    /*字符前六位移到低六位取低四位*/
  62.                 *res=base64_table[*cptr++]<<6;
  63.                 if(*cptr!='=')                                                 /*=号乎略*/
  64.                    *res++|=base64_table[*cptr++];
  65.           }
  66.         return *rptr;
  67. }
  68. char *encode(const char *cptr,char **rptr)
  69. {
  70.         char *res;
  71.         int i,clen,len;
  72.         len=strlen(cptr);
  73.         clen=len/3;
  74.         if(cptr==NULL||(res=malloc(clen+3*2+len))==NULL)
  75.                   return NULL;
  76.         for(*rptr=res;clen--;)
  77.           {
  78.                 *res++=*cptr>>2&0x3f;          /*取ptr高6位放入res低6位*/
  79.                 *res=*cptr++<<4&0x30;          /*移动ptr最低2位到高6位然后清0其 它位*/
  80.                 *res++|=*cptr>>4;                  /*取ptr高4位给res低4位*/
  81.                 *res=(*cptr++&0x0f)<<2;        /*取ptr低4位移动到高6位*/
  82.                 *res++|=*cptr>>6;                  /*取ptr高2位给res低2位*/
  83.                 *res++=*cptr++&0x3f;
  84.           }
  85.         if(i=len%3)                                       /*处理多余字符只有两种情况多一个或者两个字符*/
  86.           {
  87.                 if(i==1)                                    /*根据base64编码补=号*/
  88.                   {
  89.                         *res++=*cptr>>2&0x3f;
  90.                         *res++=*cptr<<4&0x30;
  91.                         *res++='=';
  92.                         *res++='=';
  93.                   }
  94.                 else
  95.                   {
  96.                         *res++=*cptr>>2&0x3f;
  97.                         *res=*cptr++<<4&0x30;
  98.                         *res++|=*cptr>>4;
  99.                         *res++=(*cptr&0x0f)<<2;
  100.                         *res++='=';
  101.                   }
  102.           }
  103.         *res='=';                                               /*保证最后结位为=结束原因是因为base64里有为0的编码*/
  104.         for(res=*rptr;*res!='=';res++)
  105.        *res="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[*res];
  106.         rptr[0][strlen(*rptr)-1]='\0';                 /*去掉最后一个=号*/
  107.         return *rptr;
  108. }
复制代码

贡献两个函数本来想写着转成perl用的但是目前还没有学xs还无法转换成perl模块
因为在很多地方都用到这个我也遇到了,所以自己也来个造轮子
http://bbs.chinaunix.net/viewthread.php?tid=895303&extra=page%3D1&page=1
不知道效率如何^_^



新修改base64表初始化工作谢谢思一克提醒

[ 本帖最后由 lovesaka 于 2007-2-5 21:24 编辑 ]

论坛徽章:
0
发表于 2007-02-05 02:18 |显示全部楼层
强人啊……不顶不行!

论坛徽章:
0
发表于 2007-02-05 09:55 |显示全部楼层
请问这2个函数如何调用啊
比如我只提供一个字符串

论坛徽章:
0
发表于 2007-02-05 09:58 |显示全部楼层
原帖由 01072541 于 2007-2-5 09:55 发表
请问这2个函数如何调用啊
比如我只提供一个字符串


函数已有声明:

char *decode(const char*,char **);
char *encode(const char*,char **);

--

论坛徽章:
0
发表于 2007-02-05 10:02 |显示全部楼层
但是我就一个字符串啊就一个参数
这函数需要有2个参数传入啊

论坛徽章:
0
发表于 2007-02-05 10:03 |显示全部楼层
比如char *p;
p = ewrfsdfsd;
举个例子给我看下,好不好,谢谢了

论坛徽章:
0
发表于 2007-02-05 10:05 |显示全部楼层
原帖由 01072541 于 2007-2-5 10:02 发表
但是我就一个字符串啊就一个参数
这函数需要有2个参数传入啊


开一个缓冲区,用来存放目标数据。大小为原数据长度的 4/3 多一些,就可以了。

--

论坛徽章:
0
发表于 2007-02-05 10:06 |显示全部楼层
是不是一个输入,一个输出啊
我懂了

论坛徽章:
0
发表于 2007-02-05 10:07 |显示全部楼层
原帖由 01072541 于 2007-2-5 10:06 发表
是不是一个输入,一个输出啊
我懂了


是的。楼主在变量的命名上有自己的风格。

--

论坛徽章:
0
发表于 2007-02-05 10:08 |显示全部楼层
decode函数中是每次都填BASE表?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP