卓航论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 109|回复: 2
打印 上一主题 下一主题

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

[复制链接]
[至尊红钻5级]发帖数量≥8000篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [至尊紫钻4级]金币≥20000个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 论坛元老
 UID:  7   [未点亮普号显示]钻石不足3个
 阁 分: 36567
 阁 望: 0
 阁 献: 0
 活 跃: 0
 发 贴: 12405 (0)
 阁 币: 24162  
性 别: I'm 火星人!
阅读权限: 90
在线时长: 0 小时
注册时间: 2016-10-16
最后登录: 2016-10-18
go
楼主
发表于 2016-10-17 16:26:27 |只看该作者 |倒序浏览
本帖发表于 2016-10-17 16:26:27...阅读 110 人...加油,亲爱的楼主:[db:作者]
首先我要在这里向各位纠正我犯在一个错误:Base64 只是MIME的一种编码方案,我原来所说的 MIME 其实是MIME的另一种编码方案 -- Quoted-Printable ,所以我对本文作了一些修正,并对由此而给大家带来的误导表示歉意。 May.6-01
最近在研究 POP3 时碰到一个问题,即其中的中文都是经过 MIME 编码了的,如 MS Outlook Express 是用 Base64 ,而 FoxMail 则用的是QP ,本来想找几个现成的编码/解码的代码,结果只在 UDDF 中找到一个 Delphi的 Base64 Decode ,虽然 UDDF 说是Encode/Decode ,但我是没找到 Encode的部分,而且写得不好,只好自已写一个了。
此代码是一个 BCB的单元,非常简单,提供了四个函数,要改成 Delphi 或其它 C/C++ 也很容易,有需要的自已改吧。此代码经过测试,结果正确。
补充:因为不久前有一位用 VC的朋友在引用此代码时出碰到一些困难,是由于BCB的 AnsiString的特殊性造成的,所以我将此代码改写为标准 C的,本来是应该这样的,但我习惯了用 AnsiString 所以才写成那样的,不过现在只好改写了。但为了方便 Delphi/BCB 使用,我还是特别加了一些东东,详见程序的注释,目的无非是为了更好用一些,其它语言的请自行参考吧。Mar.31-01
再补充:为了使这段程序更加实用,我将其整理为几个单元,分别用于Delphi和C++Builder 。包括对数据流 TMemoryStream 和字符串的处理。可以在本站作品中下载。Aug.14-01
修正:因为不久前一位网友给我发来MAIL说他在用些代码解码邮件附件时出错,我检查后发现我的解码函数只能处理连续字符串,而一般邮件附件都是带回车的字符串,所以我作了一点点修正,见下面的注释。Apr.03-02
下面是头文件:
//---------------------------------------------------------------------------
// MIME(QP & Base64) Encode/Decode unit. (H)
// Copyright (c) 2000, 02 Mental Studio - http://mental.mentsu.com
// Author : Raptor - raptorz@163.com
//---------------------------------------------------------------------------
#ifndef mimeb64H
#define mimeb64H
//---------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
int QPEncode(   char * const aDest, const unsigned char * aSrc, int aLen );
int QPDecode(   unsigned char * const aDest, const char * aSrc );
int Base64Encode( char * const aDest, const unsigned char * aSrc, int aLen );
int Base64Decode( unsigned char * const aDest, const char * aSrc );
#ifdef __cplusplus
}
#endif
//---------------------------------------------------------------------------
#endif
               
下面是C 文件:
//---------------------------------------------------------------------------
// MIME(QP & Base64) Encode/Decode unit. (C)
// Copyright (c) 2000, 01 Mental Studio - http://mental.mentsu.com
// Author : Raptor - raptorz@163.com
//---------------------------------------------------------------------------
//
// 如要用于Delphi ,请用如下命令编译本单元,产生 mimeb64.obj 文件:
// bcc32 -c -pr -O2 -C -K -N- -k- -d -3 -r- mimeb64.c
// 各参数意义分别为:
// -c 编译为 obj 文件
// -pr 产生 Pascal的 fastcall 调用方式
// -O2 优化选项为2
// -C 允许嵌套注释
// -K 默认使用无符号字符
// -N- 不对栈溢出作检查
// -k- 不使用标准栈框架
// -d 合并重复的字符串
// -3 使用 386 指令
// -r- 未知^_^
//
// 为方便使用,在 BCB 中可编写下面这个函数:
/*
// aOp : 0(QPEncode) 1(QPDecode) 2(Base64Encode) 3(Base64Decode)
AnsiString MimeQPBase64( AnsiString aSrc, int aOp )
{
   int n;
   TMemoryStream * buf;
   AnsiString s = "";
   buf = new TMemoryStream( );
   try
   {
     n = aSrc.Length( );
     if ( aOp == 0 )
     { // QPEncode
       buf->Size = n * 3 + 1;
       QPEncode( ( char * )( buf->Memory ), ( unsigned char * )( aSrc.c_str( ) ), n );
     }
     else if ( aOp == 2 )
     { // Base64Encode
       buf->Size = n * 4 / 3 + 1;
       Base64Encode( ( char * )( buf->Memory ), ( unsigned char * )( aSrc.c_str( ) ), n );
     }
     else
     {
       buf->Size = n + 1;
       if ( aOp == 1 ) // QPDecode
         n = QPDecode( ( unsigned char * )( buf->Memory ), aSrc.c_str( ) );
       else       // Base64Decode
         n = Base64Decode( ( unsigned char * )( buf->Memory ), aSrc.c_str( ) );
       ( ( char * )( buf->Memory ) )[n] = 0;
     }
     s = AnsiString( ( char * )( buf->Memory ) );
   }
   __finally
   {
     delete buf;
   }
   return s;
}
*/
// 在 Delphi 中则要编写下面这个单元:
/*
Unit Mime;
Interface
Function MimeQPBase64( aSrc : String; aOp : Integer ) : String;
Implementation
{$L mimeb64.obj}
Function QPEncode(   aDest : PChar; aSrc : PByte; aLen : Integer ) : Integer; External;
Function QPDecode(   aDest : PByte; aSrc : PChar         ) : Integer; External;
Function Base64Encode( aDest : PChar; aSrc : PByte; aLen : Integer ) : Integer; External;
Function Base64Decode( aDest : PByte; aSrc : PChar         ) : Integer; External;
// 因为DELPHI不包含string.h中的函数,所以要写这么个函数
Function _strlen( aStr : PChar ) : Integer; cdecl;
Begin
   Result := Length( aStr );
End;
// aOp : 0(MimeEncode) 1(MimeDecode) 2(Base64Encode) 3(Base64Decode)
Function MimeQPBase64( aSrc : String; aOp : Integer ) : String;
Var
   n  : Integer;
   buf : TMemoryStream;
Begin
   Result := '';
   buf := TMemoryStream.Create;
   Try
     n := Length( aSrc );
     If ( aOp = 0 ) Then
     Begin // QPEncode
       buf.Size := n * 3 + 1;
       QPEncode( PChar( buf.Memory ), PByte( PChar( aSrc ) ), n );
     End
     Else If ( aOp = 2 ) Then
     Begin // Base64Encode
       buf.Size := n * 4 DIV 3 + 1;
       Base64Encode( PChar( buf.Memory ), PByte( PChar( aSrc ) ), n );
     End
     Else
     Begin
       buf.Size := n + 1;
       If ( aOp = 1 ) Then // QPDecode
         n := QPDecode( PByte( buf.Memory ), PChar( aSrc ) )
       Else         // Base64Decode
         n := Base64Decode( PByte( buf.Memory ), PChar( aSrc ) );
       PByteArray( buf.Memory )[n] := 0;
     End;
     Result := PChar( buf.Memory );
   Finally
     buf.Free;
   End;
End;
*/
// 之后便可以使用MimeQPBase64这个函数了。注意:编译时要保证 mimeb64.obj 在搜索路径中。
// 其它语言直接使用这四个函数即可。
//
#include
#include "mimeb64.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// 4bit binary to char 0-F
char Hex2Chr( unsigned char n )
{
   n &= 0xF;
   if ( n = 'a' && c = '0' && c = 'A' && c = 'A' && c = 'a' && c = '0' && c > 4 );
     *p++ = Hex2Chr( *aSrc++ );
   }
   *p = 0; // aDest is an ASCIIZ string
   return ( p - aDest ); // exclude the end of zero
}
//---------------------------------------------------------------------------
// aDest 所指的缓冲区必须至少为 aSrc 长度的 1/3 !!!
// 返回 aDest的长度
int QPDecode( unsigned char * const aDest, const char * aSrc )
{
   unsigned char * p = aDest;
   int       n = strlen( aSrc );
   unsigned char  ch, cl;
   while ( *aSrc ) // aSrc is an ASCIIZ string
   {
     if ( ( *aSrc == '=' ) && ( n - 2 > 0 ) )
     {
       ch = Chr2Hex( aSrc[1] );
       cl = Chr2Hex( aSrc[2] );
       if ( ( ch == ( unsigned char )-1 ) || ( cl == ( unsigned char )-1 ) )
         *p++ = *aSrc++;
       else
       {
         *p++ = ( ch > 2 );
       t = ( *aSrc++ > 4 ) );
       t = ( *aSrc++ > 6 ) );
       *p++ = Base2Chr( *aSrc++ );
       break;
     }
   }
   if ( aLen % 3 != 0 )
   {
     *p++ = Base2Chr( t );
     if ( aLen % 3 == 1 )
       *p++ = '=';
     *p++ = '=';
   }
   *p = 0; // aDest is an ASCIIZ string
   return ( p - aDest ); // exclude the end of zero
}
//---------------------------------------------------------------------------
// aDest 所指的缓冲区必须至少为 aSrc 长度的 0.75 倍!!!
// 返回 aDest的长度
int Base64Decode( unsigned char * const aDest, const char * aSrc )
{
   unsigned char * p = aDest;
   int       i, n = strlen( aSrc );
   unsigned char  c, t;
   for ( i = 0; i > 4 ) );
       t = ( unsigned char )( c > 2 ) );
       t = ( unsigned char )( c
分享到: QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏0 支持支持0 反对反对0

使用道具 举报

[至尊红钻3级]发帖数量≥1000篇 [至尊黄钻1级]威望≥10点 [未点亮至尊蓝钻]在线时间不足10小时 [至尊绿钻1级]贡献度≥10点 [至尊紫钻9级]金币≥8000000个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 高级会员
 UID:  4   [未点亮普号显示]钻石不足3个
 阁 分: 999851780
 阁 望: 100
 阁 献: 101
 活 跃: 0
 发 贴: 1381 (0)
 阁 币: 999850098  
性 别: I'm 火星人!
阅读权限: 50
在线时长: 1 小时
注册时间: 2016-10-14
最后登录: 2016-10-24
沙发
发表于 2016-10-18 12:58:09 |只看该作者
本回复帖发表于 2016-10-18 12:58:09,感谢沙漠虫子对本帖的认真回复,你的回复是对楼主莫大的鼓舞
沙发!沙发!

使用道具 举报

[至尊红钻2级]发帖数量≥100篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [未点亮至尊紫钻]金币不足100个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 注册会员
 UID:  29   [未点亮普号显示]钻石不足3个
 阁 分: 111
 阁 望: 1
 阁 献: 4
 活 跃: 0
 发 贴: 104 (0)
 阁 币: 1  
性 别: I'm 火星人!
阅读权限: 20
在线时长: 2 小时
注册时间: 2011-1-6
最后登录: 2016-10-20
板凳
发表于 2016-10-19 23:14:20 |只看该作者
本回复帖发表于 2016-10-19 23:14:20,感谢za402对本帖的认真回复,你的回复是对楼主莫大的鼓舞
过来看看的

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1、请认真发帖,禁止回复纯表情,纯数字等无意义的内容!帖子内容不要太简单!
2、提倡文明上网,净化网络环境!抵制低俗不良违法有害信息。
3、每个贴内连续回复请勿多余3贴,每个版面回复请勿多余10贴!
4、如果你对主帖作者的帖子不屑一顾的话,请勿回帖。谢谢合作!

手机版| 百度搜索:vkee.pw

2012-2015 卓航旗下 GMT+8, 2024-6-17 03:32 , Processed in 9.362881 second(s), 31 queries . Powered by Discuz! X3.2  

禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.如遇版权问题,请及时联系站长(QQ:5213513)

今天是: | 本站已经安全运行: //这个地方可以改颜色

快速回复 返回顶部 返回列表