用PHP实现POP3邮件的解码(二)

时间:2010-01-12 09:07:46   来源:第二电脑网  作者:第二电脑网

  第二电脑网导读:对邮件进行编码最初的原因是因为 Internet 上的很多网关不能正确传输8 bit 内码的字符,比如汉字等。编码的原理就是把 8 bit 的内容转换成 7 bit 的形式以能正确传输,在接收方收到之后,再将其还原成 8 bit 的内容。  MIME 是“多用途网际邮件扩充协议”的缩写,在 MIME 协议之前,邮件的编码曾经有过 UUENCODE 等编码方式 ,但是由于 MIME 协议算法...
  正文:

MIME 编码方式简介

  Subject: =?gb2312?B?xOO6w6Oh?=

  这里是邮件的主题,可是因为编码了,我们看不出是什么内容,其原来的文本是:“你好!”我们先看看 MIME 编码的两种方法

  对邮件进行编码最初的原因是因为 Internet 上的很多网关不能正确传输8 bit 内码的字符,比如汉字等。编码的原理就是把 8 bit 的内容转换成 7 bit 的形式以能正确传输,在接收方收到之后,再将其还原成 8 bit 的内容。

  MIME 是“多用途网际邮件扩充协议”的缩写,在 MIME 协议之前,邮件的编码曾经有过 UUENCODE 等编码方式 ,但是由于 MIME 协议算法简单,并且易于扩展,现在已经成为邮件编码方式的主流,不仅是用来传输 8 bit 的字符,也可以用来传送二进制的文件 ,如邮件附件中的图像、音频等信息,而且扩展了很多基于MIME 的应用。从编码方式来说,MIME 定义了两种编码方法Base64与QP(Quote-Printable) :

  Base 64 是一种通用的方法,其原理很简单,就是把三个Byte的数据用 4 个Byte表示,这样,这四个Byte 中,实际用到的都只有前面6 bit,这样就不存在只能传输 7bit 的字符的问题了。Base 64的缩写一般是“B”,像这封信中的Subject 就是用的 Base64 编码。

  另一种方法是QP(Quote-Printable) 方法,通常缩写为“Q”方法,其原理是把一个 8 bit 的字符用两个16进制数值表示,然后在前面加“=”。所以我们看到经过QP编码后的文件通常是这个样子:=B3=C2=BF=A1=C7=E5=A3=AC=C4=FA=BA=C3=A3=A1。

  在 PHP 里,系统有两个函数可以很方便地实现解码:base64_decode()与quoted_printable_decode(),前者可用于base64 编码的解码,后者是用于 QP 编码方法的解码。

  现在我们再来看看Subject: =?gb2312?B?xOO6w6Oh?= 这一主题的内容,这不是一段完整的编码,只有部分是编码了的,这个部分用 =? ?= 两个标记括起来,=? 后面说明的是这段文字的字符集是 GB2312 ,然后一个 ? 后面的一个 B 表示的是用的 Base64 编码。通过这段分析,我们来看一下这个 MIME 解码的函数:(该函数由 PHPX.COM 站长 Sadly 提供,本人将其放入一个类中,并做了少量的修改,在此致谢)

  function decode_mime($string) {

   $pos = strpos($string, '=?');

   if (!is_int($pos)) {

     return $string;

   }

   $preceding = substr($string, 0, $pos); // save any preceding text

   $search = substr($string, $pos+2); /* the mime header spec says this is the longest a single encoded word can be */

   $d1 = strpos($search, '?');

   if (!is_int($d1)) {

     return $string;

   }

   $charset = substr($string, $pos+2, $d1); //取出字符集的定义部分

   $search = substr($search, $d1+1); //字符集定义以后的部分=>$search;

   $d2 = strpos($search, '?');

   if (!is_int($d2)) {

     return $string;

   }

   $encoding = substr($search, 0, $d2); ////两个? 之间的部分编码方式 :q 或 b 

   $search = substr($search, $d2+1);

   $end = strpos($search, '?='); //$d2+1 与 $end 之间是编码了 的内容:=> $endcoded_text;

   if (!is_int($end)) {

     return $string;

   }

   $encoded_text = substr($search, 0, $end);

   $rest = substr($string, (strlen($preceding . $charset . $encoding . $encoded_text)+6)); //+6 是前面去掉的 =????= 六个字符

   switch ($encoding) {

   case 'Q':

   case 'q':

     //$encoded_text = str_replace('_', '%20', $encoded_text);

     //$encoded_text = str_replace('=', '%', $encoded_text);

     //$decoded = urldecode($encoded_text);

   $decoded=quoted_printable_decode($encoded_text);

     if (strtolower($charset) == 'windows-1251') {

     $decoded = convert_cyr_string($decoded, 'w', 'k');

     }

     break;

   case 'B':

   case 'b':

     $decoded = base64_decode($encoded_text);

     if (strtolower($charset) == 'windows-1251') {

     $decoded = convert_cyr_string($decoded, 'w', 'k');

     }

     break;

   default:
来源:http://www.002pc.com/master/College/Programming/PHP/11740.html

收藏到:

关于《用PHP实现POP3邮件的解码(二)》文章的评论

共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面

随机文章

    SQL Error: select * from ***_ecms_article where classid='86' and checked=1 order by rand() limit 10

顶出来的热门

    SQL Error: select * from ***_ecms_article where classid='86' and checked=1 order by diggtop desc,id desc limit 10
站内搜索: 高级搜索

热门搜索: Windows style 系统 tr IP QQ CPU 安装 function 注册 if td