Base64编码的原理及实现(源码)
2012-12-24 12:58
567 查看
Base64编码在邮件中最为常见,呵呵,因为我最近就是在做邮箱报警,SMTP验证就是Base64编码用户名和密码进行验证的,并且附件也是要转换成base64编码的数据,然后再发送的。该编码使用64个明文来编码任意的二进制文件,它里面只使用了A-Z,a-z,0-9,+,/这64个字符。编码里面还有“=”号啊,不过等号不属于编码字符,而是填充字符。
我在网上查了很多关于Base64编码代码,大都比较的复杂和冗长,还有,Base64编码函数内尽量不要有strlen()这个函数,因为当我获取图片数据时,明明read返回54,strlen却为4,可能中间有些'\0'吧。
所以,一气之下,就自己写了一个。
一、base64编码原理:
1)base64的编码都是按字符串长度,以每3个8bit的字符为一组,
2)然后针对每组,首先获取每个字符的ASCII编码,
3)然后将ASCII编码转换成8bit的二进制,得到一组3*8=24bit的字节
4)然后再将这24bit划分为4个6bit的字节,并在每个6bit的字节前面都填两个高位0,得到4个8bit的字节
5)然后将这4个8bit的字节转换成10进制,对照Base64编码表 ,得到对应编码后的字符。
二、源码:
static const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//chsrc为源数据,chdes为Base64编码后的数据,len为数据长度
void Base64_Code(unsigned char* chsrc, unsigned char* chdes, int len)
{
unsigned char char_array_3[3], char_array_4[4];
int i = 0, j = 0;
while(len--)
{
char_array_3[i++] = *(chsrc++);
if(3 == i)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; i < 4; i++)
*(chdes+i) = base64_chars[char_array_4[i]];
i = 0;
chdes += 4;
}
}
if(i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(j = 0; j < (i+1); j++)
*(chdes++) = base64_chars[char_array_4[j]];
while((3 > i++))
*(chdes++) = '=';
}
*chdes = '\0';
return;
}
顺便用C++模仿写一个吧(因为我是用作邮箱报警的,所以,Base64编码是Email中的一个操作):
string Email::base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len)
{
string dest;
int i = 0, j = 0;
unsigned char char_array_3[3], char_array_4[4];
while(in_len--)
{
char_array_3[i++] = *(bytes_to_encode++);
if (3 == i)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; i < 4; i++)
dest += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; j < (i + 1); j++)
dest += base64_chars[char_array_4[j]];
while((i++ < 3))
dest += '=';
}
return dest;
}
Base64解码我就不管了,因为一般用到的情况很少,而且,最重要的是,我目前还用不到。
我在网上查了很多关于Base64编码代码,大都比较的复杂和冗长,还有,Base64编码函数内尽量不要有strlen()这个函数,因为当我获取图片数据时,明明read返回54,strlen却为4,可能中间有些'\0'吧。
所以,一气之下,就自己写了一个。
一、base64编码原理:
1)base64的编码都是按字符串长度,以每3个8bit的字符为一组,
2)然后针对每组,首先获取每个字符的ASCII编码,
3)然后将ASCII编码转换成8bit的二进制,得到一组3*8=24bit的字节
4)然后再将这24bit划分为4个6bit的字节,并在每个6bit的字节前面都填两个高位0,得到4个8bit的字节
5)然后将这4个8bit的字节转换成10进制,对照Base64编码表 ,得到对应编码后的字符。
二、源码:
static const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//chsrc为源数据,chdes为Base64编码后的数据,len为数据长度
void Base64_Code(unsigned char* chsrc, unsigned char* chdes, int len)
{
unsigned char char_array_3[3], char_array_4[4];
int i = 0, j = 0;
while(len--)
{
char_array_3[i++] = *(chsrc++);
if(3 == i)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; i < 4; i++)
*(chdes+i) = base64_chars[char_array_4[i]];
i = 0;
chdes += 4;
}
}
if(i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(j = 0; j < (i+1); j++)
*(chdes++) = base64_chars[char_array_4[j]];
while((3 > i++))
*(chdes++) = '=';
}
*chdes = '\0';
return;
}
顺便用C++模仿写一个吧(因为我是用作邮箱报警的,所以,Base64编码是Email中的一个操作):
string Email::base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len)
{
string dest;
int i = 0, j = 0;
unsigned char char_array_3[3], char_array_4[4];
while(in_len--)
{
char_array_3[i++] = *(bytes_to_encode++);
if (3 == i)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; i < 4; i++)
dest += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; j < (i + 1); j++)
dest += base64_chars[char_array_4[j]];
while((i++ < 3))
dest += '=';
}
return dest;
}
Base64解码我就不管了,因为一般用到的情况很少,而且,最重要的是,我目前还用不到。
相关文章推荐
- 关于base64编码的原理及实现--for SMTP
- 关于base64编码的原理及实现
- Base64实现编码、解码原理
- 关于base64编码的原理及实现
- 关于base64编码的原理及实现
- Base64编码的原理与Java实现
- Base64编码的原理及实现
- 关于base64编码的原理及实现
- 不借助工具手动按原理实现图片转BASE64字符串编码
- Base64 编码的原理及实现
- 关于base64编码的原理及实现
- Base64编码原理解析与Java实现
- base64编码的原理及实现
- base64编码的原理及实现
- [置顶] 关于base64编码的原理及实现
- 关于base64编码的原理及实现
- 【知识笔记】Base64编码解码原理及手动实现(C#)
- Base64编码原理与实现
- Base64编码原理与实现