//<cpp-begin>和<cpp-end>之间为BASE64.cpp的完整内容.BASE64.h文件中仅包含函数原型,不包含其他任何内容.
//<cpp-begin>
//BASE64,v1.0.001
//base64加密解密模块
//updated:2024-04-23
//
#include "BASE64.h"
#ifndef NULL
#define NULL 0
#endif
static const char BASE64_CHARSA[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64编码字符表(ANSI)
char BASE64_FILLUPA = '=';//填充字符
typedef union base64_value
{
unsigned long value;
unsigned char bytes[4];
}BASE64_VALUE;
//编码函数
/************************************************************
pstrEncoded:指向密文缓冲区的指针[输出]
ulSize :申明密文缓冲区可以容纳的最大字节数量(含空中止)
pstrText :指向明文缓冲区的指针[输入]
返回值:0表示参数错误;其他值为密文的字符数量(不含空中止).
注:
仅当输出缓冲区可以容纳编码后的所有密文时,函数才能完成编码;
否则可能导致输出缓冲区内容被修改且不是想要的结果;
************************************************************/
unsigned long BASE64_EncodedA(char * pstrEncoded, unsigned long ulSize, const char * pstrText)
{
unsigned long ulLenOfText = 0;
unsigned long ulLenOfEncoded = 0;
unsigned long i = 0;
unsigned char ucChar = 0, ucPiece = 0;
BASE64_VALUE sValue = { 0 };
BASE64_VALUE * psEncoded = (BASE64_VALUE*)pstrEncoded;
//基本参数检查,不允许明文指针为空
if (NULL == pstrText) return 0;
//统计明文的字符数量
while (0 != pstrText[ulLenOfText])
{
ulLenOfText++;
}
//基本参数检查,不允许明文长度为零.
if (0 == ulLenOfText) return 0;
//对明文进行编码,每3字节明文转换成4字节编码文本,不足3字节的部分补充“填充符”.
for (i = 0; i < ulLenOfText; i++)
{
ucPiece = i % 3;
sValue.bytes[2 - ucPiece] = pstrText[i];//Intel系列的内存字节顺序为低端序
//sValue.bytes[ucPiece] = pstrText[i];//高端序(不使用,仅作为备注参考)
if ((ulLenOfText - 1) == i || 2 == ucPiece)
{//到达原文本结尾处,或,已经取出了3个字符
if (NULL != psEncoded && (ulLenOfEncoded + 4) < ulSize)
{ //输出缓冲区不为空,且,当前即将操作的位置没有超过最大长度限制;
//满足条件时才会输出密文,否则仅计算输出缓冲区需要的空间;
//明文3字节共24位,按顺序拆分成4个6位.
//1st byte of encoded;
ucChar = (unsigned char)((sValue.value << 8) >> 26);
psEncoded->bytes[0] = BASE64_CHARSA[ucChar];
//2nd byte of encoded
ucChar = (unsigned char)((sValue.value << 14) >> 26);
psEncoded->bytes[1] = BASE64_CHARSA[ucChar];
//3th byte of encoded
ucChar = (unsigned char)((sValue.value << 20) >> 26);
psEncoded->bytes[2] = BASE64_CHARSA[ucChar];
//4th byte of encoded
ucChar = (unsigned char)((sValue.value << 26) >> 26);
psEncoded->bytes[3] = BASE64_CHARSA[ucChar];
//检查是否需要补充填充字符
if (1 == ucPiece)//需要补充1个填充字符
{
psEncoded->bytes[3] = BASE64_FILLUPA;
}
if (0 == ucPiece)//需要补充2个填充字符
{
psEncoded->bytes[2] = BASE64_FILLUPA;
psEncoded->bytes[3] = BASE64_FILLUPA;
}
psEncoded++;
}
ulLenOfEncoded += 4;
sValue.value = 0;//重置(必要操作,当明文长度不是3的整数倍时会导致值异常).
}
}
if(NULL != psEncoded) psEncoded->bytes[0] = 0;//补充空中止
return ulLenOfEncoded;
}
//解码函数
/************************************************************
pstrText :指向明文缓冲区的指针[输出]
ulSize :申明明文缓冲区可以容纳的最大字节数量(含空中止)
pstrEncoded:指向密文缓冲区的指针[输入]
返回值:0表示参数错误;其他值为明文的字符数量(不含空中止).
注:
仅当输出缓冲区可以容纳解码后的所有明文时,函数才能完成解码;
否则可能导致输出缓冲区内容被修改且不是想要的结果;
************************************************************/
unsigned long BASE64_DecodedA(char * pstrText, unsigned long ulSize, const char * pstrEncoded)
{
unsigned long ulLenOfText = 0;
unsigned long ulLenOfEncoded = 0;
unsigned long ulIndex = 0;
unsigned long i = 0;
unsigned char j = 0;
BASE64_VALUE sValue = { 0 };
unsigned char cChar = 0, ucPiece = 0;
//基本参数检查,不允许密文指针为空
if (NULL == pstrEncoded) return 0;
//统计密文长度
while (0 != pstrEncoded[ulLenOfEncoded])
{
ulLenOfEncoded++;
}
//密文长度不能为零值,且必须是4的整数倍.
if (0 == ulLenOfEncoded || 0 != (ulLenOfEncoded % 4)) return 0;
//对密文进行解码,每4字节密文转换成3字节明文
for (i = 0; i < ulLenOfEncoded; i++)
{
ucPiece = i % 4;
sValue.bytes[ucPiece] = pstrEncoded[i];
//由密文字符转换成索引值
for (j = 0; j < 64; j++)
{
if (BASE64_CHARSA[j] == sValue.bytes[ucPiece])
{
sValue.bytes[ucPiece] = j;
break;
}
}
if (j == 64) sValue.bytes[ucPiece] = 0;//填充符(或非法字符)处理
if ((ulLenOfEncoded - 1) == i || 3 == ucPiece)
{//到达密文结尾处,或,已取出4字节
if (NULL != pstrText && (ulLenOfText + 3) < ulSize)
{ //输出缓冲区不为空,且,当前即将操作的位置没有超过最大长度限制;
//[密文]1~4字节中仅后6位是需要的字节位,共24位(即转换后的3字节);
//取值顺序同编码函数,采用高端序字节顺序进行解码;
//位操作比乘法快,所以采用位操作来计算需要的结果.
//[密文]第4字节的345678位组成明文第3字节的低6位,[密文]第3字节的78位组成明文第3字节的高2位.
cChar = ((sValue.bytes[3] << 2) >> 2 ) | (sValue.bytes[2] << 6 );
pstrText[ulLenOfText + 2] = cChar;
//[密文]第3字节的3456位组成明文第2字节的低4位,[密文]第2字节的5678位组成明文第2字节的高4位.
cChar = ((sValue.bytes[2] << 2) >> 4) | (sValue.bytes[1] << 4);
pstrText[ulLenOfText + 1] = cChar;
//[密文]第2字节的34位组成明文第1字节的低2位,[密文]第1字节的345678位组成明文第1字节的高6位.
cChar = (sValue.bytes[1] >> 4) | (sValue.bytes[0] << 2);
pstrText[ulLenOfText + 0] = cChar;
}
ulLenOfText += 3;
//sValue.value = 0;//重置(非必要操作,密文长度限定为4的整数倍);
}
}
if (NULL != pstrText) pstrText[ulLenOfText] = 0;//补充空中止
return ulLenOfText;
}
//<cpp-end>
用法简单:
#include <iostream>
using namespace std;
#include "BASE64.h"
void main()
{
char strOut[1024] = { 0 };
char strOut2[1024] = { 0 };
Str_CopyA(strOut, "thisisatesttext...");//复制一串文本,用于验证空中止设置正确与否;
cout << "len:" << BASE64_EncodedA(strOut, 1024, "Username:") << endl;
cout << "encoded<" << strOut << ">" << endl;
Str_CopyA(strOut2, "thisisatesttext...");//复制一串文本,用于验证空中止设置正确与否;
cout << "len:" << BASE64_DecodedA(strOut2, 1024, strOut) << endl;
cout << "decoded<" << strOut2 << ">" << endl;
}