Base64编解码规则及代码实现(原创,欢迎提意见和建议)
编码规则Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在最后编码完成后在结尾替换1到2个“=”,即替换末尾的1~2个A,也就是补位。
例:将对ABC进行BASE64编码
首先取ABC对应的ASCII码值。A(65)B(66)C(67)。
再取二进制值A(01000001)B(01000010)C(01000011),然后把这三个字节的二进制码接起来(010000010100001001000011),再以6位为单位分成4个数据块并在最高位填充两个0后形成4个字节的编码后的值(00010000)(00010100)(00001001)(00000011)。蓝色部分为真实数据。再把这四个字节数据转化成10进制数得(16)(20)(9)(3)。最后根据BASE64给出的64个基本字符表,查出对应的ASCII码字符(Q)(U)(J)(D)。这里的值实际就是数据在字符表中的索引。
注BASE64字符表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
解码规则:根据编码的规则进行逆向解码
主题思想体现了 移位,& ,^ 操作 来控制2进制数据
代码实现:
// Base64.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "wtypes.h"
#include "string.h"
typedef struct _ThreeBytes_
{
_ThreeBytes_()
{
memset((void*)&byte1,0,1);
memset((void*)&byte2,0,1);
memset((void*)&byte3,0,1);
}
BYTE byte1;
BYTE byte2;
BYTE byte3;
}ThreeBytes,*LPThreeBytes;
typedef struct _FourBytes_
{
_FourBytes_()
{
memset((void*)&byte1,0,1);
memset((void*)&byte2,0,1);
memset((void*)&byte3,0,1);
memset((void*)&byte4,0,1);
}
BYTE byte1;
BYTE byte2;
BYTE byte3;
BYTE byte4;
}FourBytes,*LPFourBytes;
char strBase64[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
int FindIndex(char c)
{
for (int i=0; i<64; i++)
{
if (strBase64 == c)
{
return i;
}
}
return -1;
}
//规则转换函数1
void Translate3To4(LPThreeBytes pThreeBytes,LPFourBytes pFourBytes)
{
pFourBytes->byte1 = (pThreeBytes->byte1>>2)&0x3F;
pFourBytes->byte2 = ((pThreeBytes->byte2>>4)&0x0F)^((pThreeBytes->byte1<<4)&0x30);
pFourBytes->byte3 = ((((pThreeBytes->byte2<<4)&0xF0)^((pThreeBytes->byte3>>4)&0x0C))>>2)&0x3F;
pFourBytes->byte4 = pThreeBytes->byte3&0x3F;
pFourBytes->byte1 = (BYTE)strBase64;
pFourBytes->byte2 = (BYTE)strBase64;
pFourBytes->byte3 = (BYTE)strBase64;
pFourBytes->byte4 = (BYTE)strBase64;
}
//规则转换函数2
void Translate4To3(LPFourBytes pFourBytes,LPThreeBytes pThreeBytes)
{
FourBytes tempFourBytes;
//memcpy((void *)&tempFourBytes,pFourBytes,sizeof(FourBytes));
tempFourBytes.byte1 = (BYTE)FindIndex(pFourBytes->byte1);
tempFourBytes.byte2 = (BYTE)FindIndex(pFourBytes->byte2);
tempFourBytes.byte3 = (BYTE)FindIndex(pFourBytes->byte3);
tempFourBytes.byte4 = (BYTE)FindIndex(pFourBytes->byte4);
pThreeBytes->byte1 = (tempFourBytes.byte1<<2&0xFC)^(tempFourBytes.byte2>>4&0x03);
pThreeBytes->byte2 = (tempFourBytes.byte2<<4&0xF0)^(tempFourBytes.byte3>>2&0x0F);
pThreeBytes->byte3 = (tempFourBytes.byte3<<6&0xC0)^(tempFourBytes.byte4&0x3F);
}
//编码函数
void EncodeBase64(char *strSource, int nSourceLen, char *strDest)
{
if (strSource == NULL||nSourceLen<1)
{
return;
}
char *pSource = strSource;
char *pDest = strDest;
ThreeBytes tempThreeBytes;
FourBytes tempFourBytes;
int nPack = nSourceLen/3;
int nRemainder = nSourceLen%3;
for (int i=0; i<nPack; i++)
{
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
memcpy((void *)&tempThreeBytes,pSource,sizeof(tempThreeBytes));
Translate3To4(&tempThreeBytes,&tempFourBytes);
memcpy(pDest,(void *)&tempFourBytes,sizeof(tempFourBytes));
pSource += sizeof(tempThreeBytes);
pDest += sizeof(tempFourBytes);
}
if (nRemainder == 0)
{
return;
}
else if(nRemainder == 1)
{
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
tempThreeBytes.byte1 = strSource;
tempThreeBytes.byte2 = 0;
tempThreeBytes.byte3 = 0;
Translate3To4(&tempThreeBytes,&tempFourBytes);
memcpy(pDest,(void *)&tempFourBytes,sizeof(tempFourBytes));
pDest += sizeof(tempFourBytes);
pDest -=2;
*pDest = '=';
pDest++;
*pDest = '=';
}
else
{
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
tempThreeBytes.byte1 = strSource;
tempThreeBytes.byte2 = strSource;
tempThreeBytes.byte3 = 0;
Translate3To4(&tempThreeBytes,&tempFourBytes);
memcpy(pDest,(void *)&tempFourBytes,sizeof(tempFourBytes));
pDest += sizeof(tempFourBytes);
pDest --;
*pDest = '=';
}
}
//解码函数
void DecodeBase64(char *strSource, int nSourceLen, char *strDest)
{
if (strSource == NULL||nSourceLen<1)
{
return;
}
char *pSource = strSource;
char *pDest = strDest;
ThreeBytes tempThreeBytes;
FourBytes tempFourBytes;
int nPack = nSourceLen/4;
for (int i=0; i<nPack-1; i++)
{
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
memcpy((void *)&tempFourBytes,pSource,sizeof(tempFourBytes));
Translate4To3(&tempFourBytes,&tempThreeBytes);
memcpy(pDest,(void *)&tempThreeBytes,sizeof(tempThreeBytes));
pSource += sizeof(tempFourBytes);
pDest += sizeof(tempThreeBytes);
}
//有2个等号
if ((nSourceLen>1)&&(strSource=='='))
{
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
memcpy((void *)&tempFourBytes,pSource,sizeof(tempFourBytes));
tempThreeBytes.byte1 = ((BYTE)FindIndex(tempFourBytes.byte1)<<2&0xFC)^((BYTE)FindIndex(tempFourBytes.byte2)>>4&0x03);
memcpy(pDest,(void *)&tempThreeBytes,1);
return;
}
//有1个等号
if (strSource == '=')
{
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
memcpy((void *)&tempFourBytes,pSource,sizeof(tempFourBytes));
tempThreeBytes.byte1 = ((BYTE)FindIndex(tempFourBytes.byte1)<<2&0xFC)^((BYTE)FindIndex(tempFourBytes.byte2)>>4&0x03);
tempThreeBytes.byte2 = ((BYTE)FindIndex(tempFourBytes.byte2)<<4&0xF0)^((BYTE)FindIndex(tempFourBytes.byte3)>>2&0x0F);
memcpy(pDest,(void *)&tempThreeBytes,2);
return;
}
//没等号 此时少做了一次循环 再补上
memset((void *)&tempThreeBytes,0,sizeof(tempThreeBytes));
memset((void *)&tempFourBytes,0,sizeof(tempFourBytes));
memcpy((void *)&tempFourBytes,pSource,sizeof(tempFourBytes));
Translate4To3(&tempFourBytes,&tempThreeBytes);
memcpy(pDest,(void *)&tempThreeBytes,sizeof(tempThreeBytes));
// pSource += sizeof(tempFourBytes);
// pDest += sizeof(tempThreeBytes);
}
int main(int argc, char* argv[])
{
printf("编码******************************************\n");
char strInput = {"娃哈哈"};
printf("\"%s\" Base64编码为:",strInput);
char strOutput = {0};
EncodeBase64(strInput,strlen(strInput),strOutput);
printf("%s\n",strOutput);
printf("解码******************************************\n");
memset(strInput,0,sizeof(char)*500);
printf("\"%s\" Base64解码为:",strOutput);
DecodeBase64(strOutput,strlen(strOutput),strInput);
printf("%s\n",strInput);
return 0;
}
来源:http://hi.baidu.com/blueapple_c/blog/item/e501cb448bb6342ecffca38b.html
页:
[1]