摘 要 MIME是目前互联网邮件普遍采用的格式标准,本文通过对MIME邮件格式规范的分析和说明,给出了从邮件中提取其所含各种信息的基本方法。
关键词 MIME、邮件、格式、信息提取
1 MIME邮件格式分析
MIME技术规范的完整内容由RFC 2045-2049定义,包括了信息格式、媒体类型、编码方式等各方面的内容,这里我们只介绍其中的一些关键的格式和规范,通过了解这些格式规范,我们就可以实现以编程的方式从MIME邮件中提取基本的邮件信息。1.1 域
MIME邮件的基本信息、格式信息、编码方式等重要内容都记录在邮件内的各种域中,域的基本格式:{域名}:{内容},域由域名后面跟“:”再加上域的信息内容构成,一条域在邮件中占一行或者多行,域的首行左侧不能有空白字符,比如空格或者制表符,占用多行的域其后续行则必须以空白字符开头。域的信息内容中还可以包含属性,属性之间以“;”分隔,属性的格式如下:{属性名称}=”{属性值}”。 表1是一封示例邮件的内容,其中行1-5、行8都是单行的域,行6-7则是一个多行的域,并带有一个名为charset的属性,属性值为us-ascii。 表1 示例电子邮件行1 From: ”suntao” <suntao@fimmu.com> 行2 To: <yxj@fimmu.com> 行3 Subject: hello world 行4 Date: Mon, 9 Oct 2006 16:51:34 +0800 行5 MIME-Version: 1.0 行6 Content-Type: text/plain; 行7 charset="us-ascii" 行8 Date: Mon, 9 Oct 2006 16:48:25 +0800 行9 行10 Hello world 行11 |
1.2 Content-Type域
Content-Type域定义了邮件中所含各种内容的类型以及相关属性。邮件所含的文本、超文本、附件等信息都按照对应Content-Type域所指定的媒体类型、存储位置、编码方式等信息存储在邮件中。Content-Type域基本格式:Content-Type:{主类型}/{子类型}。示例邮件中的行6-7就是一个Content-Type域,主类型为text,子类型为plain,字符集属性为us-ascii。表2:MIME邮件中常见的主类型主类型 | 常见属性 | 参数含义 |
text | charset | 文本信息所使用的字符集 |
image | name | 图像的名称 |
application | name | 应用程序的名称 |
multipart | boundary | 邮件分段边界标识 |
1.3 multipart类型
MIME邮件中各种不同类型的内容是分段存储的,各个段的排列方式、位置信息都通过Content-Type域的multipart类型来定义。multipart类型主要有三种子类型:mixed、aLTErnative、related。1.3.1 multipart类型基本格式 ● multipart/mixed类型 如果一封邮件中含有附件,那邮件的Content-Type域中必须定义multipart/mixed类型,邮件通过multipart/mixed类型中定义的boundary标识将附件内容同邮件其它内容分成不同的段。基本格式如下:Content-Type: multipart/mixed; boundary="{分段标识}" ● multipart/aLTErnative类型 MIME邮件可以传送超文本内容,但出于兼容性的考虑,一般在发送超文本格式内容的同时会同时发送一个纯文本内容的副本,如果邮件中同时存在纯文本和超文本内容,则邮件需要在Content-Type域中定义multipart/alternative类型,邮件通过其boundary中的分段标识将纯文本、超文本和邮件的其它内容分成不同的段。基本格式如下:Content-Type: multipart/alternative; boundary="{分段标识}" ● multipart/related类型 MIME邮件中除了可以携带各种附件外,还可以将其它内容以内嵌资源的方式存储在邮件中。比如我们在发送html格式的邮件内容时,可能使用图像作为html的背景,html文本会被存储在alternative段中,而作为背景的图像则会存储在multipart/related类型定义的段中。基本格式如下:Content-Type: multipart/related; type="multipart/alternative"; boundary="{分段标识}"1.3.2 multipart类型的boundary属性 multipart的子类型中都定义了各自的boundary属性,邮件使用这些boundary中定义的字符串作为标识,将邮件内容分成不同的段,段体内的每个子段以“--”+boundary行开始,父段则以“--”+boundary+“--”行结束,不同段之间用空行分隔。1.3.3 multipart类型的层次关系表3:multipart子类型之间的层次关系Multipart/mixed | ||||||
| ||||||
附件 |
1.4 Content-Transfer-Encoding域
MIME邮件可以传送图像、声音、视频以及附件,这些非ASCII码的数据都是通过一定的编码规则进行转换后附着在邮件中进行传递的。编码方式存储在邮件的Content-Transfer-Encoding域中,一封邮件中可能有多个Content-Transfer-Encoding域,分别对应邮件不同部分内容的编码方式。目前MIME邮件中的数据编码普遍采用Base64编码或Quoted-printable编码来实现。1.4.1 Base64编码 Base64编码的目的是将输入的数据全部转换成由64个指定ASCII字符组成的字符序列, 这64个字符由{'A'-'Z', 'a'-'z', '0'-'9', '+', '/'}构成。编码时将需要转换的数据每次取出6bit,然后将其转换成十进制数字,这个数字的范围最小为0,最大为63,然后查询{'A'-'Z', 'a'-'z', '0'-'9', '+', '/'}构成的字典表,输出对应位置的ASCII码字符,这样每3个字节的数据内容会被转换成4个字典中的ASCII码字符,当转换到数据末尾不足3个字节时,则用“=”来填充。1.4.2 Quoted-printable编码 Quoted-printable编码的目的也是将输入的信息转换成可打印的ASCII码字符,但它是根据信息的内容来决定是否进行编码,如果读入的字节处于33-60、62-126范围内的,这些都是可直接打印的ASCII字符,则直接输出,如果不是,则将该字节分为两个4bit,每个用一个16进制数字来表示,然后在前面加“=”,这样每个需要编码的字节会被转换成三个字符来表示。
[8]电大学习网.免费论文网[EB/OL]. /d/file/p/2024/0424/fontbr />
2 MIME邮件信息提取
从上面的分析可以看出,MIME邮件传递的实际是一个经过特殊编码并以约定格式排列的字符序列,我们只需要提取存储在邮件各种域中的格式、位置和编码信息,按照根据这些信息从字符序列中提取出对应的字符内容并对其进行反向解码,就可以得到我们需要的有关内容。下面给出.Net环境下,利用C#结合正则表达式从邮件中提取相关信息的基本思路和部分代码。2.1 收件人/发件人/邮件主题的提取
收件人、发件人、邮件主题是一封邮件的基本组成信息,分别存邮件的From域、To域、Subject域中。开发中只需要通过正则表达式来匹配这些指定的域,然后从匹配结果中取出相关信息即可。 示例代码:提取邮件主题string emailContent = “……”;//emailContent中存储的是邮件内容pat = @"^Subject:/s*(?<title>.*)/s*/r/n";myMatches = Regex.Matches(emailContent,pat,RegexOptions.Multiline);foreach(Match nextMatch in myMatches){ GroupCollection myGroup = nextMatch.Groups; string title = myGroup["title"].ToString();//title变量存储From域的内容 ……} 需要注意的是上面的代码提取的是跟随在Subject:后面的字符串,如果邮件的主题内容是中文或者其它需要编码的地区文字,则还需要对其进行解码。比如,如果邮件的Subject域中的信息是“你好”,那么提取出来的字符串会是这种形式:=?gb2312?B?xOO6ww==?=, 论文检测天使-免费论文检测软件http://www.jiancetianshi.com第一个?同第二个?之间的gb2312代表标题内容所使用的字符集,第二个?和第三个?之间的B代表这部分内容采用的是base64编码方式,如果采用Quoted-printabel编码方式则显示Q,第三个?和第四个?之间则是“你好”经过base64编码后的字符串。
2.2 multipart分段信息的提取
邮件通过multipart类型将内容分隔成不同的段,各段之间的边界标识由对应multipart类型的boundary属性定义。要从邮件中提取出需要的内容,首先需要提取出邮件中的分段信息。下面的代码从一封邮件中提取出所有的multipart类型的名称和boundary属性。示例代码:提取multipart信息string emailContent = “……”;//emailContent中存储的是邮件内容string pat = @"/bContent-Type:/s*(?<type>/w+//w+);/s+(type=/S(?<subtype>/S+)/S)?/s+boundary=""(?<flag>/S+)""";MatchCollection myMatches = Regex.Matches(emailContent,pat);foreach(Match nextMatch in myMatches){ GroupCollection myGroup = nextMatch.Groups; string type = myGroup["type"].ToString();//type变量存储multipart类型的名称 string flag = myGroup["flag"].ToString();//flag变量存储multipart类型的boundary属性 ……}2.3 邮件附件的提取
邮件中的附件信息由对应的Content-Type域、Content-Transfer-Encoding域、Content-Disposition域和multipart/mixed类型定义,前三个域定义附件的类型、名称和编码方式,multipart/mixed则定义附件同邮件其它内容的分段标识。基本格式如下:--boundary分段标识 Content-Type: application/msword; name="readme.doc" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=" readme.doc " …… 文件内容的Base64编码 …… --boundary分段标识 |
FileStream fs = new FileStream("c://" + fileName,
FileMode.CreateNew); BinaryWriter bw = new BinaryWriter(fs); bw.Write(attachFile); bw.Close(); fs.Close();} 上面的程序从邮件原文中提取出附件信息,并根据附件采用的编码类型进行解码,然后将解码后的内容按照原文件名存储到C盘根目录。同样,如果附件的文件名是中文或者其它需要编码的文字,则首先需要对文件名进行解码。3 总结
本文对MIME邮件的基本格式做了分析和阐述,介绍了MIME中几个重要的规范和定义,并给出了利用正则表达式从邮件内容中提取相关信息的基本思路和方法。在开发中需要注意的是,邮件中所含的内容决定了邮件的具体格式,multipart类型以及对应的分段标识只有在有相关内容的时候才会在邮件中出现,在开发时需要具体分析。MIME的详细技术规范可以查询RFC的相关文档。参考文献
[1] Francois Liger,C# Text Manipulation [M], Wrox Press Inc, 2002.[2] Internet RFC/STD/FYI/BCP Archives [EB/OL]., http://www.faqs.org/rfcs/
[8]电大学习网.免费论文网[EB/OL]. /d/file/p/2024/0424/fontbr />
相关文章:
赞自由软件(一)04-26
需要工程类施工开题报告范文吗04-26
一篇论文格式模板(如何规范撰写学术论文)04-26
如何使用学前教育专业毕业论文模板04-26
Scopus期刊分类:社会学科推荐!04-26
优秀毕业论文模板(哪些方面需要注意)04-26
增刊发表论文是核心期刊?04-26