可对任意类型数据进行编码的Base64编解码源码

来源:互联网 发布:debug python脚本 编辑:程序博客网 时间:2024/06/02 13:58

// 测试平台: 在Win2K下的Cygwin gcc编译通过,测试没有发现问题(如果你发现了还请告诉我,谢谢!)
// 调用的库: strlen() (  其实可以自己写一个类似的功能函数来取长度的 )

/*
*********************************************************************************************************
*                                         昆明XXXX有限公司
*                                             技术研发部
*
*                                  (c) Copyright 2005-2006, kmajian
*                                        All Rights Reserved
*
*                                       Base-64的编解码程序文件
*
* File : BASE64.C
* By   : kmajian
* Date : 2006-6-23
*********************************************************************************************************
*/
#include "CONFIG.H"
#include "base64.h"

#define  CH_EMPTY                     0xFF
static const uint8 baseAlp[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
*********************************************************************************************************
*                                              Base64编码
*
* 函数名称 : base64enc
* 功能描述 : 把特定内存块编码为Base64编码, 存入目的字符串
* 调用模块 : 无
* 参    数 : *sOut      目标字符缓冲区
*            *pIn       需要转变为Base64编码的内存块
*            iLen       内存块长度
* 返    回 : uint16     生成编码的长度
*********************************************************************************************************
*/
uint16 base64enc(void *pIn, uint16 iLen, char * sOut)
{
    uint8 *pBuf = ( uint8 * )pIn;
    uint8 swiBuf[ 4 ];
   
    uint16 i, n;
    uint16 iReturn = 0;
    uint16 iLenM3 = iLen % 3;
    uint16 iLenD3 = iLen / 3;
    uint16 iLenD3p;
   
    if( iLenM3 == 0 )                                 // 如果iLenM3等于0则iLenD3p就为iLenD3,否则为(iLenD3+1)
     iLenD3p = iLenD3;
    else
     iLenD3p = iLenD3;
   
    if( iLen < 1 )
    {
      return iReturn;
    }
   
    for( i = 0; i < iLenD3p; i++ )
    {
      swiBuf[ 0 ] = ( *pBuf ) >> 2;                   // 把第一个字符右移2位得到一个个目标字符
      swiBuf[ 1 ] = ( ( *pBuf ) << 4 ) & 0x30;        // 把第一个字符左移四位,然后与0x30相与,
                                                      // 得到第二个目标字符的第5、6位
      pBuf++;
      swiBuf[ 1 ] = swiBuf[ 1 ] + ( ( *pBuf ) >> 4 ); // 把第二个字符右移4位,然后与得到的目标5、6位相加
                                                      // 得到第二个目标字符
      swiBuf[ 2 ] = ( ( *pBuf ) << 2 ) & 0x3C;        // 把第二个字符左移2位,然后与0x3C相与,
                                                      // 得到第二个目标字符的第3、4、5、6位
      pBuf++;
      swiBuf[ 2 ] = swiBuf[ 2 ] + ( ( *pBuf ) >> 6 ); // 把第三个字符右移6位,然后与得到的目标3、4、5、6
                                                      // 位相加,得到第三个目标字符
      swiBuf[ 3 ] = ( *pBuf ) & 0x3F;                 // 第三个字符与0x3F相与,得到第四个目标字符
      pBuf++;
      for( n = 0; n < 4; n++ )                        // 取得需要的Base64编码
      {
        *sOut = baseAlp[ swiBuf[ n ] ];
        sOut++;
        iReturn++;
      }
    }
    switch( iLenM3 )                                  // 对不足三个字符的编码处理
    {
      case 1: swiBuf[ 0 ] = ( *pBuf ) >> 2;         
              swiBuf[ 1 ] = ( ( *pBuf ) << 4 ) & 0x30;
              swiBuf[ 2 ] = '=';
              swiBuf[ 3 ] = '=';
              for( n = 0; n < 4; n++ )
              {
                if( swiBuf[ n ] == '=' )
                {
                 *sOut = '=';
                }
                else
                {
                 *sOut = baseAlp[ swiBuf[ n ] ];
                }
                sOut++;
                iReturn++;
              }
              break;
      case 2: swiBuf[ 0 ] = ( *pBuf ) >> 2;         
              swiBuf[ 1 ] = ( ( *pBuf ) << 4 ) & 0x30;
              pBuf++;
              swiBuf[ 1 ] = swiBuf[ 1 ] + ( ( *pBuf ) >> 4 );
              swiBuf[ 2 ] = ( ( *pBuf ) << 2 ) & 0x3C;
              swiBuf[ 3 ] = '=';
              for( n = 0; n < 4; n++ )
              {
                if( swiBuf[ n ] == '=' )
                {
                 *sOut = '=';
                }
                else
                {
                 *sOut = baseAlp[ swiBuf[ n ] ];
                }
                sOut++;
                iReturn++;
              }
              break;
      default:break;
    }
   
    *sOut = '/0';
   
    return iReturn;
}

/*
*********************************************************************************************************
*                                              Base64解码
*
* 函数名称 : base64dec
* 功能描述 : 把送入的字符串按Base64方式解码, 存入目的缓冲区
* 调用模块 : 无
* 参    数 : *sIn       源字符串
*            *pOut      输出内存块
* 返    回 : uint16     解码后内容的长度
*********************************************************************************************************
*/
uint16 base64dec(const char *sIn, void * const pOut)
{
  uint8 *outBuf = ( uint8 * )pOut;
  uint8 cTemp;
  uint8 cBuf[ 3 ];
  uint16 iReturn = 0;
  uint16 i, n;
  uint16 cLen;
  uint16 aLen;
 
  cLen = strlen( sIn );
  if( ( cLen % 4 ) != 0 )
  {
   return iReturn;
  }
 
  aLen = cLen / 4;
  for( i = 0; i < aLen; i++ )
  {
   cTemp = GetB64Char( *sIn );
   sIn++;
   cBuf[ 0 ] = cTemp << 2;
   cTemp = GetB64Char( *sIn );
   sIn++;
   cBuf[ 0 ] = cBuf[ 0 ] + ( cTemp >> 4 );
   cBuf[ 1 ] = cTemp << 4;
   cTemp = GetB64Char( *sIn );
   sIn++;
   if( cTemp == CH_EMPTY )
   {
    *outBuf = cBuf[ 0 ];
    outBuf++;
    *outBuf = cBuf[ 1 ];
    iReturn = iReturn + 2;
    
    return iReturn;
   }
   else
   {
    cBuf[ 1 ] = cBuf[ 1 ] + ( cTemp >> 2 );
    cBuf[ 2 ] = cTemp << 6;
   }
   cTemp = GetB64Char( *sIn );
   sIn++;
   if( cTemp == CH_EMPTY )
   {
    *outBuf = cBuf[ 0 ];
    outBuf++;
    *outBuf = cBuf[ 1 ];
    outBuf++;
    *outBuf = cBuf[ 2 ];
    iReturn = iReturn + 3;
    
    return iReturn;
   }
   else
   {
    cBuf[ 2 ] = cBuf[ 2 ] + cTemp;
   }
   
   for( n = 0; n < 3; n++ )
   {
    *outBuf = cBuf[ n ];
    outBuf++;
    iReturn++;
   }
  }
   
  return iReturn;
}

// 获取Base64编码值
uint8 GetB64Char( const uint8 ch )
{
 uint8 n;
 
 if( ch == '=' )
 {
  return CH_EMPTY;
 }
 else
 {
  for( n = 0; n < strlen( baseAlp ); n++ )
  {
   if( ch == baseAlp[ n ] )
   {
    break;
   }
  }
  
  return n;
 }
}

/*
*********************************************************************************************************
*                                             END
*********************************************************************************************************
*/   

 

原创粉丝点击