Base64编码、解码

       Base64MIME中常用的编码方式之一,也是一种数据加密方法。

使用Base64编码可以对任何二进制数据进行编码,经过编码后变成可打印字符。在Base64中的字符有:‘A~Z’、‘a’~z’‘0’~‘9’‘+’‘/’64个字符,由这64个字符构成Base64编码表。使用Base64编码时,对待编码字符串的二进制进行重组,每6bit为一个单元,这样可以形成26 = 64个索引码。每个索引码对应Base64编码表中的一下字符。

Ø         Base64编码算法

1           依次取出编码串的6bit,得到一个索引码,查询Base64编码表,得到相应的Base64字符

2           对于不足3个或3的倍数个字符的字符串要做特殊处理

2.1           剩余一个字符(一个字节),前6bit转换成Base64字符,剩余低2位要左边补0 ,凑成6bit,然后转换成Base64字符。最后要补上两个'='

2.2           剩余二个字符(二个字节),最后剩余4bit,左边补0,凑成6bit,转换成Base64字符。最后要补上一个'='

Ø         Base64的解码

Base64解码表是以64Base64字符的值为索引值构造的一张表(Base64CharacterMap)。网上有的给解码表分配128个存储单元,也有的分配256个存储单元,其实128个 足够了(Base64最大字符的值为122)。如:‘A’的ASCII值为65,它在Base64编码表中的索引为0,那么Base64CharacterMap[65] = 0; 对于不存在的索引就定义一个标志位就行了。如Base64CharacterMap[0] = -1;

如果觉得构造解码表不好理解,可以写个函数来计算每个Base64字符在编码表的位置。如:

int GetBase64Index(const char p)

{

         if (p >= 'A' && p <= 'Z')

         {

                   return (p - 'A');

         }

         else if (p >= 'a' && p <= 'z')

         {

                   return (p - 'a' + 'Z' - 'A' + 1);

         }

         else if (p >= '0' && p <= '9')

         {

                   return (p - '0' + ('Z' - 'A' + 1) * 2);

         }

         else if (p == '+')

         {

                   return 62;

         }

         else if (p == '/')

         {

                   return 63;

         }

         else

         {

                   return -1;

         }

}

Ø         算法实现

²        方法一:

typedef unsigned char Byte;

const char Base64CharacterSet[] =

{

    'A', 'B', 'C', 'D', 'E', 'F', 'G',

    'H', 'I', 'J', 'K', 'L', 'M', 'N',

    'O', 'P', 'Q', 'R', 'S', 'T',

    'U', 'V', 'W', 'X', 'Y', 'Z',

  'a', 'b', 'c', 'd', 'e', 'f', 'g',

    'h', 'i', 'j', 'k', 'l', 'm', 'n',

    'o', 'p', 'q', 'r', 's', 't',

    'u', 'v', 'w', 'x', 'y', 'z',

  '0', '1', '2', '3', '4', '5',

    '6', '7', '8', '9', '+', '/'

};

void Base64Encode(const Byte *pByte, int nByteLen, string &sResult)

{

         int nLoop = nByteLen / 3;

         int nRemain = nByteLen % 3;

         int i = 0;

 

         for (i=0; i < nLoop; ++i)

         {

                   int nIndex1 = pByte[i*3] >> 2;

                   int nIndex2 = ((pByte[i*3] & 0x03) << 4) | ((pByte[i*3+1] & 0xF0)  >> 4);

                   int nIndex3 = ((pByte[i*3+1] & 0x0F) << 2) | ((pByte[i*3+2] & 0xc0) >> 6);

                   int nIndex4 = (pByte[i*3+2] & 0x3F);

 

                   sResult += Base64CharacterSet[nIndex1];

                   sResult += Base64CharacterSet[nIndex2];

                   sResult += Base64CharacterSet[nIndex3];

                   sResult += Base64CharacterSet[nIndex4];

         }

 

         if (nRemain == 1)

         {

                   int nIndex1 = pByte[i*3] >> 2;

                   int nIndex2 = (pByte[i*3] & 0x03);

                   sResult += Base64CharacterSet[nIndex1];

                   sResult += Base64CharacterSet[nIndex2];

                   sResult += "==";

         }

         else if (nRemain == 2)

         {

                   int nIndex1 = pByte[i*3] >> 2;

                   int nIndex2 = ((pByte[i*3] & 0x03) << 4) | (pByte[i*3+1] >> 4);

                   int nIndex3 = (pByte[i*3+1] & 0x0F);

 

                   sResult += Base64CharacterSet[nIndex1];

                   sResult += Base64CharacterSet[nIndex2];

                   sResult += Base64CharacterSet[nIndex3];

                   sResult += "=";

         }

         else

         {

                   sResult += "";

         }

}

解码

void Base64Decode(const Byte *pSrc, int nLen, string &sDest)

{

         for (int i=0; i < nLen; i += 4)

         {

                   int nVal1 = GetBase64Index(pSrc[i]);

                   int nVal2 = GetBase64Index(pSrc[i+1]);

                   int nVal3 = GetBase64Index(pSrc[i+2]);

                   int nVal4 = GetBase64Index(pSrc[i+3]);

                  if (-1 != nVal3)   //第三个字符不为'=',说明源字符串3*n+2

                   {

                            sDest += (nVal1 << 2) | (nVal2 >> 4);

                            if (-1 != nVal4)   //第四个字符不为'=',说明源字符串3*n

                            {

                                     sDest += (nVal2 << 4) | (nVal3 >> 2);

                                     sDest += (nVal3 << 6) | nVal4;

                            }

                            else  //3*n+2

                            {

                                     sDest += (nVal2 << 4) | nVal3;

                            }

                   }

                   else  //3*n+1

                   {

                            sDest += (nVal1 << 2) | nVal2;

                   }

                  

         }

}

²        方法二:

        typedef unsigned long uint32;

union Base64Block

{

         Byte bytes[4];

         uint32 uBase64Block;

};

 

void Base64Encode(const Byte *pByte, int nByteLen, string &sResult)

{

         Base64Block block;

         uint32 uMask = 0x3F;

     for (int i=0, nLeft = nByteLen; i < nByteLen; i+=3, nLeft -= 3)

     {

              block.bytes[2] = pByte[i];

              if (nLeft > 1)

              {

                       block.bytes[1] = pByte[i+1];

                       if (nLeft > 2)

                       {

                                 block.bytes[0] = pByte[i];

                       }

                       else

                       {

                                 block.bytes[0] = 0;

                       }

              }

              else

              {

                       block.bytes[0] = 0;

                       block.bytes[1] = 0;

              }

    

              sResult += Base64CharacterSet[(block.uBase64Block >> 18) & uMask];

              sResult += Base64CharacterSet[(block.uBase64Block >> 12 & uMask];

 

              if (nLeft > 1)

              {

                       sResult += Base64CharacterSet[(block.uBase64Block >> 6) & uMask];

                       if (nLeft > 2)

                       {

                                 sResult += Base64CharacterSet[block.uBase64Block & uMask];

                       }

                       else

                       {

                                 sResult += "=";

                       }

              }

              else

              {

                       sResult += '==";

              }

     }

}

解码待续.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值