|
常见的编码还有 quote-printable, uuencode
转以前自己写的编码介绍 在MIME邮件中进行的编码有base64 Quoted-Printable方法 这里进行一下介绍
Base64是MIME邮件中常用的编码方式之一。它的主要思想是将输入的字符串或数据编码成只含有{'A'-'Z', 'a'-'z', '0'-'9', '+', '/'}这64个可打印字符的串,故称为“Base64”。
Base64编码的方法是,将输入数据流每次取6 bit,用此6 bit的值(0-63)作为索引去查表,输出相应字符。这样,每3个字节将编码为4个字符(3×8 → 4×6);不满4个字符的以'='填充。
const char EnBase64Tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
解码是编码的反过程
Quoted-Printable也是MIME邮件中常用的编码方式之一。同Base64一样,它也将输入的字符串或数据编码成全是ASCII码的可打印字符串。
Quoted-Printable编码的基本方法是:输入数据在33-60、62-126范围内的,直接输出;其它的需编码为“=”加两个字节的HEX码(大写)。为保证输出行不超过规定长度,可在行尾加“=\r\n”序列作为软回车。
一般邮件的Content-Transfer-Encoding:中会说明邮件使用的算法 如果是标题的话 那么会用B表示BASE64 用Q表示Quoted-Printable。 以下是标题的一个例子 Subject: =?gb2312?B?xOO6w6Oh?= =?和?=间表示是标题内容 gb2312表示字符集B表示base64后面是编码
下面是base64编解码过程和quoted-printable解码过程 (没有经过充分测试) 想学习的话可以看邮件 也就是把邮件导出 然后用文本工具看就OK了
[code] #include <stdio.h> #include <string.h>
static char base64_encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// encode to BASE 64 // return buflen int base64_enc(char *buf,char*text,int size) { int buflen = 0 ;
while(size>0){ *buf++ = base64_encoding[ (text[0] >> 2 ) & 0x3f]; if(size>2){ *buf++ = base64_encoding[((text[0] & 3) << 4) | ((text[1] >> 4) & 0x0f)]; *buf++ = base64_encoding[((text[1] & 0xF) << 2) | ((text[2] >> 6) &3)]; *buf++ = base64_encoding[text[2] & 0x3F]; }else{ switch(size){ case 1: *buf++ = base64_encoding[(text[0] & 3) << 4 ]; *buf++ = '='; *buf++ = '='; break; case 2: *buf++ = base64_encoding[((text[0] & 3) << 4) | ((text[1] >> 4) & 0x0f)]; *buf++ = base64_encoding[((text[1] & 0xF) << 2) | ((text[2] >> 6) &3)]; *buf++ = '='; break; } }
text +=3; size -=3; buflen +=4; }
*buf = 0; return buflen; }
static char get_base64_value(char ch,char default_value) { if ((ch >= 'A') && (ch <= 'Z')) return ch - 'A'; if ((ch >= 'a') && (ch <= 'z')) return ch - 'a' + 26; if ((ch >= '0') && (ch <= '9')) return ch - '0' + 52; switch (ch) { case '+': return 62; case '/': return 63; case '=': /* base64 padding */ return default_value; default: return default_value; } }
//进行base64解码 返回buf中内容长度 //注意 如果是最后一个字符 那么长度不准备 可能会多1 int base64_dec(char *buf,char*text,int *size) { char chunk[4]; int parsenum=0;
int linelen=*size; *size =0;
while(linelen>*size){ if(get_base64_value(*text,-1)==-1){ text++; size++; continue; }
if(linelen-*size<3) return parsenum;
chunk[0] = get_base64_value(text[0],0); chunk[1] = get_base64_value(text[1],0); chunk[2] = get_base64_value(text[2],0); chunk[3] = get_base64_value(text[3],0);
*buf++ = (chunk[0] << 2) | (chunk[1] >> 4); *buf++ = (chunk[1] << 4) | (chunk[2] >> 2); *buf++ = (chunk[2] << 6) | (chunk[3]);
if(text[1]=='='){ *size+=1; return parsenum+1; } else if(text[2]=='='){ *size+=2; return parsenum+2; } else if(text[3]=='='){ *size+=3; return parsenum+3; }
text+=4; *size+=4; parsenum+=3; }
return parsenum; }
//解码Quoted-Printable,返回解码的长度 int QPrintable_dec(char *buf,char*text,int size) { int buflen=0; // 输出的字符计数 int i=0;
while (size>0) { if (strncmp(text, "=\r\n", 3) == 0) // 软回车,跳过 { text += 3; size -= 3; } else { if (*text == '=') // 是编码字节 { sscanf(text, "=%02X", buf); buf++; text += 3; size -= 3; } else // 非编码字节 { *buf++ = (unsigned char)*text++; size--; }
buflen++; } }
return buflen; }
main() { char s[]="试一试看"; char d[100],db[100]; int len = base64_enc(d,s,strlen(s)); d[len]=0; printf("orig string is %d len:\n%s\nafter encode is %d len:\n",strlen(s),s,len ,d);
len = base64_dec(db,d,&len); db[len]=0; printf("after decode is %d len:\n%s\n",len,db);
return 0; }
[/cpde]
|