MIME和BASE64编码/解码程序代码

2022-07-04 20:05

文档管理软件,文档管理系统,知识管理系统,档案管理系统的技术资料:
作者:猛禽
最近在研究 POP3 时碰到一个问题,即其中的中文都是经过编码了的, 如 MS Outlook Express 是用 BASE64 ,而 FoxMail 则用的是 MIME , 本来想找几个现成的编码/解码的代码,结果只在 UDDF 中找到一个 Delphi 的 BASE64 Decode , 虽然 UDDF 说是 Encode/Decode ,但我是没找到 Encode 的部分,而且写得不好, 只好自已写一个了。
此代码是一个 BCB 的单元,非常简单,提供了四个函数, 此代码经过测试,结果正确。
下面是头文件:
//---------------------------------------------------------------------------
// MIME & BASE64 Encode/Decode unit. (H)
// Copyright (c) 2000 Mental Studio - http://mentals.126.com
// Author : Raptor - raptorz@126.com
//---------------------------------------------------------------------------
#ifndef mimeb64H
#define mimeb64H
//---------------------------------------------------------------------------
AnsiString MimeEncode( AnsiString s );
AnsiString MimeDecode( AnsiString s );
AnsiString Base64Encode( AnsiString s );
AnsiString Base64Decode( AnsiString s );
//---------------------------------------------------------------------------
#endif

下面是 CPP 文件:
//---------------------------------------------------------------------------
// MIME & BASE64 Encode/Decode unit. (CPP)
// Copyright (c) 2000 Mental Studio - http://mentals.126.com
// Author : Raptor - raptorz@126.com
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "mimeb64.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// 4bit binary to char 0-F
char Hex2Chr( Byte n )
{
n &= 0xF;
if ( n < 10 )
return ( char )( n + ““0““ );
else
return ( char )( n - 10 + ““A““ );
}
//---------------------------------------------------------------------------
// char 0-F to 4bit binary
Byte Chr2Hex( char c )
{
c = toupper( c );
if ( c >= ““0““ && c <= ““9““ )
return ( int )( c - ““0““ );
else if ( c >= ““A““ && c <= ““F““ )
return ( int )( c - ““A““ + 10 );
else
return -1;
}
//---------------------------------------------------------------------------
// Base64 code table
// 0-63 : A-Z(25) a-z(51), 0-9(61), +(62), /(63)
char __fastcall Base2Chr( Byte n )
{
n &= 0x3F;
if ( n < 26 )
return ( char )( n + ““A““ );
else if ( n < 52 )
return ( char )( n - 26 + ““a““ );
else if ( n < 62 )
return ( char )( n - 52 + ““0““ );
else if ( n == 62 )
return ““+““;
else
return ““/““;
}
//---------------------------------------------------------------------------
Byte Chr2Base( char c )
{
if ( c >= ““A““ && c <= ““Z““ )
return ( Byte )( c - ““A““ );
else if ( c >= ““a““ && c <= ““z““ )
return ( Byte )( c - ““a““ + 26 );
else if ( c >= ““0““ && c <= ““9““ )
return ( Byte )( c - ““0““ + 52 );
else if ( c == ““+““ )
return 62;
else
return 63;
}
//---------------------------------------------------------------------------
//
AnsiString MimeEncode( AnsiString s )
{
AnsiString asTemp = "";
int i = 1, n = s.Length( );
while ( i <= n )
{
asTemp += ““=““;
asTemp += Hex2Chr( ( Byte )( s[i] >> 4 ) );
asTemp += Hex2Chr( ( Byte )( s[i] ) );
i++;
}
return asTemp;
}
//---------------------------------------------------------------------------
//
AnsiString MimeDecode( AnsiString s )
{
AnsiString asTemp = "";
int i = 1, n = s.Length( );
Byte ch, cl; // 因为有些软件(e.g.Foxmail)对一些 < 0x7f 的字符不编码,此函数作了一些修改
while ( i <= n )
{
if ( ( s[i] == ““=““ ) && ( i + 2 <= n ) )
{
ch = Chr2Hex( s[i + 1] );
cl = Chr2Hex( s[i + 2] );
if ( ( ch == ( Byte )-1 ) || ( cl == ( Byte )-1 ) )
asTemp += s[i]; // 未编码的““=““
else
{
asTemp += ( char )( ( ch << 4 ) | cl );
i += 2;
}
}
else
asTemp += s[i]; // 未编码的字符
i++;
}
return asTemp;
}
//---------------------------------------------------------------------------
//
AnsiString Base64Encode( AnsiString s )
{
int n = s.Length( );
Byte c, t;
AnsiString asTemp = "";
for ( int i = 1; i <= n; i++ )
{
c = s[i];
if ( i % 3 == 1 )
{
asTemp += Base2Chr( c >> 2 );
t = ( c << 4 ) & 0x3F;
}
else if ( i % 3 == 2 )
{
asTemp += Base2Chr( t | ( c >> 4 ) );
t = ( c << 2 ) & 0x3F;
}
else
{
asTemp += Base2Chr( t | ( c >> 6 ) );
asTemp += Base2Chr( c );
}
}
if ( n % 3 != 0 )
{
asTemp += Base2Chr( t );
if ( n % 3 == 1 )
asTemp += "==";
else
asTemp += "=";
}
return asTemp;
}
//---------------------------------------------------------------------------
//
AnsiString Base64Decode( AnsiString s )
{
int n = s.Length( );
Byte c, t;
AnsiString asTemp = "";
for ( int i = 1; i <= n; i++ )
{
if ( s[i] == ““=““ )
break;
c = Chr2Base( s[i] );
if ( i % 4 == 1 )
t = c << 2;
else if ( i % 4 == 2 )
{
asTemp += ( char )( t | ( c >> 4 ) );
t = ( Byte )( c << 4 );
}
else if ( i % 4 == 3 )
{
asTemp += ( char )( t | ( c >> 2 ) );
t = ( Byte )( c << 6 );
}
else
asTemp += ( char )( t | c );
}
return asTemp;
}
//---------------------------------------------------------------------------