LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 800|回复: 2

base64编码,解码

[复制链接]
发表于 2003-9-11 07:04:09 | 显示全部楼层 |阅读模式
以前写的一个小程序.

  1. /*
  2. * 将二进制数据转换为ascii -- encodebase64
  3. * 将ascii转换为二进制数据 -- decodebase64
  4. * 使用base64编码
  5. *      XZJ          2003.04.08
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. char encodingTable [64] = {

  10.     'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',

  11.     'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',

  12.     'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',

  13.     'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
  14. };


  15. int encodebase64 (unsigned char htext[], unsigned char h64[],
  16.                  size_t htextlen ) {

  17.     unsigned long ixtext;
  18.     unsigned long lentext;
  19.     unsigned long origsize;
  20.     unsigned long ix;
  21.     long ctremaining;
  22.     unsigned char ch;
  23.     unsigned char inbuf [3], outbuf [4];
  24.     unsigned char *ph64;
  25.     short i;
  26.     short charsonline = 0, ctcopy;

  27.     ixtext = ix=0;
  28.     ph64=h64;

  29.     lentext=htextlen;

  30.     while (1) {

  31.         ctremaining = lentext - ixtext;

  32.         if (ctremaining <= 0)
  33.             break;

  34.         for (i = 0; i < 3; i++) {

  35.             ix = ixtext + i;

  36.             if (ix < lentext)
  37.                 inbuf[i]=htext[ix];
  38.                 else
  39.                 inbuf [i] = 0;
  40.         } /*for*/

  41.         outbuf [0] = (inbuf [0] & 0xFC) >> 2;

  42.         outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);

  43.         outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);

  44.         outbuf [3] = inbuf [2] & 0x3F;

  45.         ctcopy = 4;

  46.         switch (ctremaining) {

  47.         case 1:
  48.             ctcopy = 2;

  49.             break;

  50.         case 2:
  51.             ctcopy = 3;

  52.             break;
  53.         } /*switch*/

  54.         for (i = 0; i < ctcopy; i++)
  55.             *ph64++=encodingTable[outbuf[i]];

  56.         for (i = ctcopy; i < 4; i++)
  57.             *ph64++='=';

  58.         ixtext += 3;

  59.     } /*while*/

  60.     return (1);
  61. }


  62. int decodebase64 (unsigned char h64[], unsigned char htext[],size_t h64len) {

  63.     unsigned long ixtext;
  64.     unsigned long lentext;
  65.     unsigned long origsize;
  66.     unsigned long ctremaining;
  67.     unsigned char ch;
  68.     unsigned char inbuf [3], outbuf [4];
  69.     short i, ixinbuf;
  70.     unsigned char *phtext;
  71.     int flignore;
  72.     int flendtext = 0;

  73.     ixtext = 0;

  74.     lentext = h64len;

  75.     ixinbuf = 0;

  76.     phtext=htext;

  77.     while (1) {

  78.         if (ixtext >= lentext)
  79.             break;

  80.         ch=h64[ixtext++];

  81.         flignore = 0;


  82.         if ((ch >= 'A') && (ch <= 'Z'))
  83.             ch = ch - 'A';

  84.         else if ((ch >= 'a') && (ch <= 'z'))
  85.             ch = ch - 'a' + 26;

  86.         else if ((ch >= '0') && (ch <= '9'))
  87.             ch = ch - '0' + 52;

  88.         else if (ch == '+')
  89.             ch = 62;

  90.         else if (ch == '=') /*no op -- can't ignore this one*/
  91.             flendtext = 1;

  92.         else if (ch == '/')
  93.             ch = 63;

  94.             else
  95.             flignore = 1;

  96.         if (!flignore) {

  97.             short ctcharsinbuf = 3;
  98.             int flbreak = 0;

  99.             if (flendtext) {

  100.                 if (ixinbuf == 0)
  101.                     break;

  102.                 if ((ixinbuf == 1) || (ixinbuf == 2))
  103.                     ctcharsinbuf = 1;
  104.                     else
  105.                     ctcharsinbuf = 2;

  106.                 ixinbuf = 3;

  107.                 flbreak = 1;
  108.             }

  109.             inbuf [ixinbuf++] = ch;

  110.             if (ixinbuf == 4) { /*将读入的4个字节decode */

  111.                 ixinbuf = 0;

  112.                 outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4);

  113.                 outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C)
  114. >> 2);                                                                                                                  

  115.                 outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F);

  116.                 for (i = 0; i < ctcharsinbuf; i++)
  117.                     *phtext++=outbuf[i];
  118.             }

  119.             if (flbreak)
  120.                 break;
  121.         }
  122.     } /*while*/

  123. exit:

  124.     return (1);
  125. }

  126. /* for testing */
  127. #if 0
  128. int main(int argc,char *argv[])
  129. {
  130.     unsigned char inbuf[7];
  131.     unsigned char outbuf[32];

  132.     int i;
  133.     size_t inlen,outlen;
  134.     inlen=sizeof(inbuf);
  135.     outlen=sizeof(outbuf);
  136.     memset(inbuf,0x0,inlen);
  137.     memset(outbuf,0x0,outlen);

  138.     printf("init value :\n");
  139.     for(i=0;i<inlen;++i) inbuf[i]='x';
  140.     for(i=0;i<inlen;++i)
  141.         printf("%x ",inbuf[i]);
  142.     printf("\n");

  143.     printf("encoding ... \n");
  144.     encodebase64(inbuf,outbuf,inlen);

  145.         printf("%c ",outbuf[i]);
  146.     printf("\n");

  147.     decodebase64(outbuf,inbuf,outlen);

  148.     printf("decode ...\n");
  149.     for(i=0;i<inlen;++i)
  150.         printf("%x ",inbuf[i]);
  151.     printf("\n");

  152.     return 0;
  153. }
  154. #endif
复制代码
发表于 2003-9-11 09:34:03 | 显示全部楼层
谢谢,以后写代理需要HTTP认证时可以用到,呵呵
发表于 2003-9-11 12:19:17 | 显示全部楼层
我也写了一份
不过功能相对简单

[php]
// encode to BASE 64
// return buflen
int CBaseFun::Base64Enc(unsigned char *buf,const unsigned char*text,int size)
{
        static char *base64_encoding =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        int buflen = 0 ;

        while(size>0){
                *buf++ = base64_encoding[ (text[0] >> 2 ) & 0x3f];
                if(size>2){
                        *buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
                        *buf++ = base64_encoding[((text[1] & 0xF) << 2) | (text[2] >> 6)];
                        *buf++ = base64_encoding[text[2] & 0x3F];
                }else{
                        switch(size){
                                case 1:
                                        *buf++ = base64_encoding[(text[0] & 3) << 4 ];
                                        *buf++ = '=';
                                        *buf++ = '=';
                                        break;
                                case 2:
                                        *buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
                                        *buf++ = base64_encoding[((text[1] & 0x0F) << 2) | (text[2] >> 6)];
                                        *buf++ = '=';
                                        break;
                        }
                }

                text +=3;
                size -=3;
                buflen +=4;
        }

        *buf = 0;
        return buflen;
}

char CBaseFun::GetBase64Value(char ch)
{
        if ((ch >= 'A') && (ch <= 'Z'))
                return ch - 'A';
        if ((ch >= 'a') && (ch <= 'z'))
                return ch - 'a' + 26;
        if ((ch >= '0') && (ch <= '9'))
                return ch - '0' + 52;
        switch (ch) {
                case '+':
                        return 62;
                case '/':
                        return 63;
                case '=': /* base64 padding */
                        return 0;
                default:
                        return 0;
        }
}

//进行base64解码输入应该是4的倍数(根据mime标准)
//如果不是4倍数返回错误
//注意 如果是最后一个字符 那么长度不准备 可能会多1
//返回buf长度
int CBaseFun::Base64Dec(unsigned char *buf,const unsigned char*text,int size)
{
        if(size%4)
                return -1;
        unsigned char chunk[4];
        int parsenum=0;

        while(size>0){
                chunk[0] = GetBase64Value(text[0]);
                chunk[1] = GetBase64Value(text[1]);
                chunk[2] = GetBase64Value(text[2]);
                chunk[3] = GetBase64Value(text[3]);

                *buf++ = (chunk[0] << 2) | (chunk[1] >> 4);
                *buf++ = (chunk[1] << 4) | (chunk[2] >> 2);
                *buf++ = (chunk[2] << 6) | (chunk[3]);

                text+=4;
                size-=4;
                parsenum+=3;
        }

        return parsenum;
}
[/php]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表