可对任意类型数据进行编码的Base64编解码源码
2006-06-23 12:51
330 查看
// 测试平台: 在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
*********************************************************************************************************
*/
// 调用的库: 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
*********************************************************************************************************
*/
相关文章推荐
- 数据结构与算法:单链表(利用万能指针实现对任意类型数据进行操作)
- 使用简单的json.dumps方法对简单数据类型进行编码
- 写一个方法对任意引用数据类型数组进行排序(入门级慎看,很难!!!)
- 参考C语言的qsort函数实现一个一个能对任意数据类型(包括结构体)的数组进行排序的函数(里面用的不是快速排序)
- JSON: Python Objects与String之间转换【json.dumps把python任意数据类型转换成字符串,json.loads把字符串转换为unicode编码】
- Python教程学习简记1--Python数据类型和变量 字符串和编码 list和tuple 条件判断 循环 dict和set
- Python教程学习简记1--Python数据类型和变量 字符串和编码 list和tuple 条件判断 循环 dict和set
- 对Map里的数据进行封装(数据类型和判空处理)
- MongoDB进行MapReduce的数据类型
- MongoDB进行MapReduce的数据类型
- 从键盘输入任意一个String类型的字符串 将其进行字符串反串
- mysql数据使用非默认编码进行查询的问题
- sql使用cast进行数据类型转换示例
- OC中Foundation集合的使用(其中包括基本数据类型与对象进行转换)
- 【C#】对“xxxx::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用。
- tomcat5中,为了保证get数据采用UTF8编码,在server.xml中进行了如下设置
- 别再重复造轮子了,利用list创建任意数据类型的链表
- 通过Ajax进行POST提交JSON类型的数据到SpringMVC Controller的方法
- JSP对浏览器发送来的数据进行重新编码的两种方案
- J2SE基础篇——数据类型、执行过程、进制、编码