荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: cycker (TryToDoEverythingOnLinux), 信区: Program
标  题: 电子邮件的MINE/Base64编码和解码和解码c++实现
发信站: 荔园晨风BBS站 (Wed Jun 25 14:11:21 2003), 站内信件

电子邮件的MINE/Base64编码和解码及C语言的实现
   吉林大学通信工程学院 刘景仰

    MINE(Multipurpose Internet Mail
Extesion)是为了电子邮件能发送非ASCII字符而定义的。因此MINE邮件不仅
能发送文本而且还能传送声音,图像,程序等二进制信息。它通过编码将二进
制信息转为字符信息进行传送。接收端在经过解码得到原来的信息。
MINE邮件的首部包含了From To,Subject等信息之外,还包括MINE的首部信息,比如:
    MINE-Version:1.0
    Content-type:tept/plain:charset:GB2321_CHARSET
    Content-Transfer-Extending:Base64
    MINE的编码方案有很多种,BASE64只是其中的一种。以下介绍Base64的算法
,并附上C语言的实现(VC++6.0调试通过)

    1,MINE/Base64的编码要将传送的讯息转为64个ASCII字符:'A'->'Z','a'->'z';
'0'~'9'; '+';'/ '。就是说文件通过MINE/Base64编码后只能出现上述的64个字符。

    2,建立符号到数字的映射:

    数字 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    字符 A B C D E F G H I J K L M N O P
    数字 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    字符 Q R S T U V W X Y Z a b c d e f
    数字 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
    字符 g h i j k l m n o p q r s t u v
    数字 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    字符 w x y z 0 1 2 3 4 5 6 7 8 9 + /

    3,把需要处理的二进制流排成一行,从高位开始,每6位为一个单位,把这个6位
转化为相应的数字,从上述的映射表中在找出对应这个数字的字符。重新整理成一个
字符流。
    如:有一个字符流'ABCD',它原来用ASCII码进行编码,形成二进制流:
    0100,0001 0100,0010 0100,0011 0100,0100
    上述二进制流以6位为单位重新整理为:
    010000 010100 001001 000011 010001 00
    末尾一组不足6位,在不足六位的低4位补零:
    010000 010100 001001 000011 010001 000000
    对应的数字为:16,20,9,3,17,0 找到映射表中对应的字母为:
    Q U J D R A
    4,字符流'ABCD'还需要补足两个字节,总的字节数才能被3整除,后面补上两个'='
    所以'ABCD'的MINE/Base64编码为:QUJDRA= =.
    附上C语言的实现:


    //Base64.h
    ////////////////////
    class CBase64
    {
    public:
    CBase64(char* pSour);
    ~CBase64();
    public:
    void Encode();
    void Decode();
    public:
    char* pDes;
    public:
    int nSourLen;
    int nDestLen;
    private:
    char *pSr;
    };
    /////////////////////////////////////////////////////////////
    //Base64.cpp
    ////////////////////////////////


    #include "Base64.h"
    #include "stdio.h"
    #define NULL 0
    ////////////////////////////////
    CBase64::CBase64(char *pSour)
    {
    int nLen;
    for( nLen=0;*(pSour+nLen)!='\0';nLen++);
    nSourLen=nLen;
    pSr=pSour;
    }

    CBase64::~CBase64()
    {
    delete[] pDes;
    }
    void CBase64::Encode()
     {
char *pD;
if(!(nSourLen%3))
nDestLen=(nSourLen/3)*4;
else
nDestLen=(nSourLen/3)*4+4;

pDes=new char[nDestLen];
pD=pDes;
int i=0,group;
char cMap[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char ch,cha;
group=nSourLen/3;

do
{
ch=*pSr;
ch=ch>>2;
ch=ch&(0x3f);
*(pDes++)=cMap[ch];
ch=*pSr;
cha=*(pSr+1);
ch=ch<<4;
ch=ch&(0x30);
cha=cha>>4;
cha=cha&(0x0f);
cha+=ch;
*(pDes++)=cMap[cha];
ch=*(pSr+1);
cha=*(pSr+2);
ch=ch<<2;
ch=ch&(0x3c);
cha=cha>>6;
cha=cha&(0x03);
ch+=cha;
*(pDes++)=cMap[ch];
ch=*(pSr+2);
ch=ch&(0x3f);
*(pDes++)=cMap[ch];
i++;
pSr+=3;
}while(i<group);

if((nSourLen%3)==1)
{
ch=*pSr;
ch=ch>>2;
ch=ch&(0x3f);
*(pDes++)=cMap[ch];
ch=*pSr;
ch=ch<<4;
ch=ch&(0x30);
*(pDes++)=cMap[ch];
*(pDes++)='=';
*(pDes)='=';
}

if((nSourLen%3)==2)
{
ch=*pSr;
ch=ch>>2;
ch=ch&(0x3f);
*(pDes++)=cMap[ch];
ch=*pSr;
cha=*(pSr+1);
ch=ch<<4;
ch=ch&(0x30);
cha=cha>>4;
cha=cha&(0x0f);
cha+=ch;
*(pDes++)=cMap[cha];
ch=(*pSr+1);
ch=ch<<2;
ch=ch&(0x3c);
*(pDes++)=cMap[ch];
*pDes='=';
}
pDes=pD;
}
////////////////////////////////////////
///测试模块

int main()
{
int nChoice;
char str[80];
int destLen;
int i;
char* pDest=NULL;

printf("\n===============MINE/Base64 Encode&Decode Test
Modual===============\n\n");
printf(" 1,Encoding using MINE/Base64.\n");
printf(" 2,Decoding using MINE/Base64.\n");
printf(" Enter a choice:");
scanf("%d",&nChoice);
printf("Make sure what you input follows the standar format.\n");
printf("String:");
scanf("%s",str);

CBase64 base(str);//Pay attention here
if(nChoice==1)
{

base.Encode();//Pay attention here!
pDest=base.pDes;//pay attention here
destLen=base.nDestLen;//pay attention here

for(i=0;i<destLen;i++)
printf("%c",*(pDest++));
}
else if(nChoice==2)
{}
else
{
return 0;
}
printf("\n");
return 1;
}
/////////////////////////////////////////////////////////

--
Welcome to CYCKER'S LINUX_SOFT FTPD ftp://192.168.36.220

※ 修改:·cycker 於 Jun 25 14:13:33 修改本文·[FROM: 192.168.36.220]
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.36.220]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店