base64编码与解码


2.解码
参考1:
// 从 data 还原 base64编码,解码的结果保存到 buffer
static void
decode_base64(uint8_t *buffer, uint16_t len, uint8_t *data)
{
    uint8_t *bp = buffer; // bp 指向最近解出的码可以存放的位置
    uint8_t *p = data; // p 指向 一组编码(四个) 的开头
    uint8_t c1, c2, c3, c4; // 每次从 data 里获得 4 个编码存到c1 ~ c4
    while (bp < buffer + len) { // 可保存解码的位置还没有超出缓冲区
        c1 = CHAR64(*p); // 假设读取了 00aaaaaa 到 c1 (a表示 1 或 0)
        c2 = CHAR64(*(p + 1)); // 假设读取了 00aabbbb 到 c2 (b表示 1 或 0)
        if (c1 == 255 || c2 == 255)
            break; // 如果遇到编码结束符 == 255 就退出解码过程

        // 八位的c1左移两位,头六位成为解码的头部
        // 用(00110000)截取八位的c2前半字节的后两位,右移四位,成为解码的尾部
        *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4); // (aaaaaa00) | (000000aa)
        if (bp >= buffer + len)
            break; // 如果超出缓冲区,就退出本次解码过程

        c3 = CHAR64(*(p + 2)); // 假设读取了 00bbbbcc 到 c3 (b 或 c 表示 1 或 0)
        if (c3 == 255)
            break; // 如果遇到编码结束符 == 255 就退出解码过程

        // 用(00001111)截取八位的c2后半字节,左移四位,成为解码的头部
        // 用(00111100)截取八位的c3中间四位,右移两位,成为解码的尾部
        *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); // (bbbb0000) | (0000bbbb)
        if (bp >= buffer + len)
            break; // 如果超出缓冲区,就退出本次解码过程

        c4 = CHAR64(*(p + 3)); // 假设读取了 00cccccc 到 c4 (c 表示 1 或 0)
        if (c4 == 255)
            break; // 如果遇到编码结束符 == 255 就退出解码过程
        // 用(00000011)截取八位的c3中最后两位,左移六位,成为解码的头部
        // c4中最后六位,成为解码的尾部
        *bp++ = ((c3 & 0x03) << 6) | c4; // (cc000000) | (00cccccc)

        p += 4; // p 移动到 下一组(四个) 编码的开头
    }
}

----------------------
参考2:
char *b64index = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

bool Base64Decode(char *code, char *txt)
{
 int len  = strlen(code);
 if(len % 4) return false;
 char *buf = new char[len];

 int i,j;
 bool p =  false;

 for(i = 0; i < len; i++)
 {
  p = false;
  for(j = 0; j < 64; j++)
  {
   if(code[i] == b64index[j] || code[i] == '=')
   {
    buf[i] = j;
    p = true;
    break;
   }
  }
 
  if(!p)
   return false;  //出现非法字符
 }

 if(code[len - 1] == '=') buf[len - 1] = 0;
 if(code[len - 2] == '=') buf[len - 2] = 0;

 for(i = 0; i < len / 4; i++)
 {
  txt[i * 3]   = buf[i * 4] << 2 & 0xFC | ( buf[i * 4 + 1] >> 4 & 0x03);
  txt[i * 3 + 1]  = buf[i * 4 + 1] << 4 & 0xF0 | ( buf[i * 4 + 2] >> 2 & 0x0F);
  txt[i * 3 + 2]  = buf[i * 4 + 2] << 6 & 0xC0 | buf[i * 4 + 3];
 }
 
 txt[len * 6 / 8] = '\0';

 delete buf;
 return true;
}

 

--------------------------------

参考3:

base64编码
/*
  *
  *Base64?
  *
  *
  *
*/
  
#include "Base64.h"
  
static const char *g_pCodes =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ;
  
static const unsigned char g_pMap[256] =
{
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
      52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
     255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
       7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
      19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
     255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
      37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
      49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     255, 255, 255, 255
};
  
CBase64::CBase64()
{
}
  
CBase64::~CBase64()
{
}
  
bool CBase64::Encode( const unsigned char *pIn, unsigned long uInLen, unsigned char *pOut, unsigned long *uOutLen)
{
     unsigned long i, len2, leven;
     unsigned char *p;
  
     if (pOut == NULL || *uOutLen == 0)
         return false ;
  
     //ASSERT((pIn != NULL) && (uInLen != 0) && (pOut != NULL) && (uOutLen != NULL));
  
     len2 = ((uInLen + 2) / 3) << 2;
     if ((*uOutLen) < (len2 + 1)) return false ;
  
     p = pOut;
     leven = 3 * (uInLen / 3);
     for (i = 0; i < leven; i += 3)
     {
         *p++ = g_pCodes[pIn[0] >> 2];
         *p++ = g_pCodes[((pIn[0] & 3) << 4) + (pIn[1] >> 4)];
         *p++ = g_pCodes[((pIn[1] & 0xf) << 2) + (pIn[2] >> 6)];
         *p++ = g_pCodes[pIn[2] & 0x3f];
         pIn += 3;
     }
  
     if (i < uInLen)
     {
         unsigned char a = pIn[0];
         unsigned char b = ((i + 1) < uInLen) ? pIn[1] : 0;
         unsigned char c = 0;
  
         *p++ = g_pCodes[a >> 2];
         *p++ = g_pCodes[((a & 3) << 4) + (b >> 4)];
         *p++ = ((i + 1) < uInLen) ? g_pCodes[((b & 0xf) << 2) + (c >> 6)] : '=' ;
         *p++ = '=' ;
     }
  
     *p = 0; // Append NULL byte
     *uOutLen = p - pOut;
     return true ;
}
  

bool CBase64::Encode(const unsigned char *pIn, unsigned long uInLen, string& strOut) 
{
    unsigned long i, len2, leven;
    strOut = "";
 
    //ASSERT((pIn != NULL) && (uInLen != 0) && (pOut != NULL) && (uOutLen != NULL));
 
 len2 = ((uInLen + 2) / 3) << 2;//编码后的字符长度,等价于((uInLen+2)/3)*4
    //if((*uOutLen) < (len2 + 1)) return false;
 
    //p = pOut;
    leven = 3 * (uInLen / 3);//前leven个字符是3的倍数,无需要补充“=”,只有最后的哪1-2个字符需要添加=号填充,uInLen%3求余即可得剩余的需要特殊处理的字符数
 //如pIn为“abcdefgh”,此时leven为6,剩余的gh需要进行特殊处理,前面6个字符可以在下面的for循环中进行编码
 //每3个字符组成一组,经过一次for循环后变成4个字符--3个8位字符拆成4个6位然后分别在4个6位前面添加两个0
    for(i = 0; i < leven; i += 3)
    {
        strOut += g_pCodes[pIn[0] >> 2];//第一个字符右移2位得高6位形成的索引组成新组的第一个字符
        strOut += g_pCodes[((pIn[0] & 3) << 4) + (pIn[1] >> 4)];//大意:当前组的第一个字符的二进制的低2位前面补两个0和第二个字符的高4位拼接成8位得到编码后的第二个字符
        strOut += g_pCodes[((pIn[1] & 0xf) << 2) + (pIn[2] >> 6)];//当前组的第二个字符的低4位(前面还加了两个0,加号前面的意义其实是0000+低四位字符,然后再左移两位,移去了高两位的0,相当于给第四位前面补了两个0),和第三个字符的高2位拼接成新的组合的第三个字符
        strOut += g_pCodes[pIn[2] & 0x3f];//取得当前组的第三个字符的低6位得base64表的索引位置(前面的两个0对索引值无意义)
        pIn += 3;
    }

 if (i < uInLen)
    {
        unsigned char a = pIn[0];
        unsigned char b = ((i + 1) < uInLen) ? pIn[1] : 0;
        unsigned char c = 0;
 
        strOut += g_pCodes[a >> 2];
        strOut += g_pCodes[((a & 3) << 4) + (b >> 4)];
        strOut += ((i + 1) < uInLen) ? g_pCodes[((b & 0xf) << 2) + (c >> 6)] : '=';
        strOut += '=';
    }
 
    //*p = 0; // Append NULL byte
    //*uOutLen = p - pOut;
    return true;
}

  
bool CBase64::Decode( const string& strIn, unsigned char *pOut, unsigned long *uOutLen) 
{
     unsigned long t, x, y, z;
     unsigned char c;
     unsigned long g = 3;
  
     //ASSERT((pIn != NULL) && (uInLen != 0) && (pOut != NULL) && (uOutLen != NULL));
  
     for (x = y = z = t = 0; x < strIn.length(); x++)
     {
         c = g_pMap[strIn[x]];
         if (c == 255) continue ;
         if (c == 254) { c = 0; g--; }
  
         t = (t << 6) | c;
  
         if (++y == 4)
         {
             if ((z + g) > *uOutLen) { return false ; } // Buffer overflow
             pOut[z++] = (unsigned char )((t>>16)&255);
             if (g > 1) pOut[z++] = (unsigned char )((t>>8)&255);
             if (g > 2) pOut[z++] = (unsigned char )(t&255);
             y = t = 0;
         }
     }
  
     *uOutLen = z;
     return true ;
}

 引用自:http://my.youkuaiyun.com/cclongying1989/code/detail/13009

 

ascii码表:http://baike.baidu.com/view/15482.htm?fromId=812    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值