|
- 编码规则
- 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[i] == 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->byte1];
- pFourBytes->byte2 = (BYTE)strBase64[pFourBytes->byte2];
- pFourBytes->byte3 = (BYTE)strBase64[pFourBytes->byte3];
- pFourBytes->byte4 = (BYTE)strBase64[pFourBytes->byte4];
- }
- //规则转换函数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[nSourceLen - 1];
- 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[nSourceLen - 2];
- tempThreeBytes.byte2 = strSource[nSourceLen - 1];
- 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[nSourceLen - 2]=='='))
- {
- 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[nSourceLen - 1] == '=')
- {
- 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[500] = {"娃哈哈"};
- printf(""%s" Base64编码为:",strInput);
- char strOutput[500] = {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/ ... b6342ecffca38b.html |
|