|
在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了
- #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;
- }
复制代码 |
|