﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>学习日记 &#187; email</title>
	<atom:link href="https://www.softwareace.cn/?cat=28&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://www.softwareace.cn</link>
	<description>时刻想着为自己的产品多做一些对他好的事情</description>
	<lastBuildDate>Fri, 20 Mar 2026 06:58:28 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>邮件相关开源库</title>
		<link>https://www.softwareace.cn/?p=1573</link>
		<comments>https://www.softwareace.cn/?p=1573#comments</comments>
		<pubDate>Wed, 21 Dec 2016 05:16:37 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1573</guid>
		<description><![CDATA[http://code.csdn.net/news/2819419 http://sourceforge.ne [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>http://code.csdn.net/news/2819419</p>
<p>http://sourceforge.net/projects/vmime/?source=dlp</p>
<p>http://sourceforge.net/projects/libmail/?source=recommended</p>
<p>http://sourceforge.net/projects/lhmail/?source=dlp</p>
<p>http://sourceforge.net/projects/nlcreator/?source=dlp</p>
<p>http://trojita.flaska.net/download.html</p>
<p>http://sourceforge.net/projects/davmail/?source=recommended</p>
<p>http://sourceforge.net/projects/evolution.mirror/?source=dlp</p>
<p>http://www.oschina.net/p/trustedbird</p>
<p>http://www.oschina.net/p/trojita</p>
<p>http://www.oschina.net/p/yorba</p>
<p>http://www.oschina.net/p/sylpheed</p>
<p>http://www.oschina.net/p/libquickmail http://sourceforge.net/projects/libquickmail/?source=directory</p>
<p>http://www.oschina.net/p/claws+mail</p>
<p>Thunderbird</p>
<p>http://www.oschina.net/p/enigmail</p>
<p>http://www.oschina.net/p/lightning</p>
<p>http://www.oschina.net/p/quicktext 模板分组的工具</p>
<p>http://www.oschina.net/p/libsmtp 一个允许开发者通过stmp协议发送邮件的c库<br />
http://www.oschina.net/p/libextractemail 用于从文本中提取所有的 email 地址。<br />
http://www.oschina.net/p/ripmime ripMIME 用来解析电子邮件中的附件<br />
http://www.oschina.net/p/gmime ，用来根据 MIME 解析和创建邮件的。</p>
<p>http://www.oschina.net/p/libesmtp</p>
<p>http://sourceforge.net/projects/smtpmail/?source=directory</p>
<p>ios<br />
http://www.oschina.net/p/shemailvalidator SHEmailValidator 提供对电子邮件地址的有效性验证。</p>
<p>http://www.oschina.net/p/SMTPSender</p>
<p>http://www.oschina.net/p/mbcontactpicker 关联选择工具库</p>
<p>php<br />
http://www.oschina.net/p/libgmailer libgmailer是一个用于访问GMail的PHP函数包</p>
<p>outlook<br />
http://www.oschina.net/p/pstviewtool 发布Outlook数据查看工具。<br />
http://www.oschina.net/p/undbx 用来从 Outlook Express 的 .dbx 文件从提取、恢复删除的邮件</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1573</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>配置Exchange 2010+Outlook 2010自动发现功能</title>
		<link>https://www.softwareace.cn/?p=1529</link>
		<comments>https://www.softwareace.cn/?p=1529#comments</comments>
		<pubDate>Thu, 27 Oct 2016 10:12:01 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1529</guid>
		<description><![CDATA[从Exchange 2007+Outlook 2007开始，Microsoft提供了一种新的配置Outlook [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>从Exchange 2007+Outlook 2007开始，Microsoft提供了一种新的配置Outlook客户端的方式：自动发现（Auto Discover）。用户只需要打开Outlook，按照向导的提示走完所有步骤，最理想的情况下（客户端已经加入域并登录到域），用户只需要点击鼠标，不必用键盘输入任何信息，就能够连接到Exchange服务器。而且，可以同时配置Outlook MAPI模式和Outlook Anywhere模式。</p>
<p>在一个加入域的客户端上，启动Outlook，通过自动发现功能进行配置的情况，用户无需输入任何信息就能直接创建到Exchange的连接。</p>
<p>而对于与Exchange服务器不在一个林中的客户端（客户端加入了其它域/客户端在工作组模式），通过自动发现进行配置时，就需要输入身份验证信息才能够连接了。</p>
<p>那么，这个功能是如何实现的呢？</p>
<p>自动发现功能需要Exchange服务器和Outlook客户端都是2007/2010版本。这两个版本中，服务器和客户端之间可以通过Web Service进行联系，获取相关的配置信息。下面以Exchange 2010+Outlook 2010为例进行介绍，整个配置步骤对于Exchange 2007/Outlook 2007同样适用。</p>
<p>自动发现服务的实质是，Outlook客户端通过DNS查询，连接到指定域的Exchange客户端访问服务器上，提交身份验证信息后，从服务器下载一个XML文件。Outlook通过这个XML文件所包含的信息，配置到Exchange服务器的连接方式。</p>
<p>自动发现服务需要一个访问连接点（Service Connection Point，SCP），Outlook客户端必须能够按照内置的规则，查询并连接到该SCP才能实现自动发现。</p>
<p><strong>自动发现的查询步骤</strong></p>
<p>假设客户的邮件域名为contoso.com，在没有加入域的客户端上，Outlook会进行3次尝试，只要其中任意一步成功连接，后续步骤就不再进行。如果3次都没有成功获取XML文件，Outlook将放弃尝试，并告知用户需要进行手动配置。</p>
<ol>
<li>https://contoso.com/Autodiscover/Autodiscover.xml</li>
<li>https://autodiscover.contoso.com/Autodiscover/Autodiscover.xml</li>
<li>查询DNS是否注册有名称为_autodiscover的SRV服务记录，如果有，获取该服务记录所指定的主机名称（A记录）。假设找到SRV记录，指向主机mail.contoso.com。那么Outlook会尝试连接：
<p>https://mail.contoso.com/autodiscover/autodiscover.xml</li>
</ol>
<p>以下截图是从一台加入PTCDemo.com的客户端，通过AutoDiscover去连接位于PCOE.com的Exchange服务器， 也就是前面第2段视频的场景下，客户端所发起的连接尝试：</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/55.png"><img title="5" src="http://fesd77.files.wordpress.com/2011/01/5_thumb5.png?w=667&amp;h=453" alt="5" width="667" height="453" border="0" /></a></p>
<p>从上图可以看到，对于加入域的客户端，会优先使用本站点Exchange客户端访问服务器上指定的AutoDiscoverServiceInternalUri值。这个值可以通过以下命令进行查询，其中的<em>pcoeexchhtcas1</em>是Exchange客户端访问服务器名称。<br />
Get-ClientAccessServer<span style="font-size: medium;"><span style="color: #333333;"><span style="font-family: Georgia;"> <em>pcoeexchhtcas1</em> | select AutoDiscoverServiceInternalUri<br />
</span></span></span><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/18.png"><img title="1" src="http://fesd77.files.wordpress.com/2011/01/1_thumb8.png?w=700&amp;h=90" alt="1" width="700" height="90" border="0" /></a></p>
<p>需要注意的是，所有的连接尝试都是通过HTTPS加密方式进行的，因此要求：1、Exchange服务器上配置有名称与该SCP主机名相同的证书；2、Outlook客户端必须信任该证书。关于证书的配置方式，可以查看前面的文章：《<a style="color: #743399;" href="http://fesd77.wordpress.com/2010/12/28/exchange-server-2010%e7%9a%84%e8%af%81%e4%b9%a6%e9%85%8d%e7%bd%ae%e4%b8%8a/" target="_blank"><span style="font-family: Georgia; font-size: medium;">Exchange Server 2010的证书配置</span></a>》。</p>
<p><strong>配置Internet上的DNS服务器记录</strong></p>
<p>根据前面的步骤，可以看到，对于企业内网，并且已经登录到活动目录的客户端，只需要保证能够正常连接到AutoDiscoverServiceInternalUri中指定的Uri就可以实现客户端的自动配置了。而要在Internet上实现Outlook自动发现，需要选择以下3种方式之一对进行DNS配置：</p>
<ol>
<li>将contoso.com的Internet域名解析指向Exchange客户端访问服务器</li>
<li>将主机记录（A记录）autodiscover.contoso.com的解析指向Exchange客户端访问服务器</li>
<li>注册Exchange客户端访问服务器的主机记录，并创建一个名称为_autodiscover的SRV服务记录，指向该A记录</li>
</ol>
<p>这里提到的“将解析指向”，简单来说，就是在客户端PING这个域名或主机名，能够获取到Exchange客户端访问服务器在Internet上的IP地址。</p>
<p>AutoDiscover主机记录可以利用别名（CNAME）来代替，例如在Windows的DNS中，可以注册一个CNAME记录，指向实际的Exchange主机。</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/3-1.png"><img title="3-1" src="http://fesd77.files.wordpress.com/2011/01/3-1_thumb.png?w=403&amp;h=453" alt="3-1" width="403" height="453" border="0" /></a></p>
<p>SRV记录的注册方式，可以参考以下知识库文档：<br />
<a style="color: #0066cc;" href="http://support.microsoft.com/kb/940881/en-us"><span style="font-family: Georgia; font-size: medium;">http://support.microsoft.com/kb/940881/en-us</span></a><br />
以下是在Windows的DNS服务中注册的情况：</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/29.png"><img title="2" src="http://fesd77.files.wordpress.com/2011/01/2_thumb9.png?w=893&amp;h=235" alt="2" width="700" height="184" border="0" /></a></p>
<p>这个SRV记录的详细信息如下：<br />
<a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/36.png"><img title="3" src="http://fesd77.files.wordpress.com/2011/01/3_thumb6.png?w=407&amp;h=450" alt="3" width="407" height="450" border="0" /></a></p>
<p><strong>修改Exchange服务器的URL设置</strong></p>
<p>在安装Exchange 2010 CAS服务器角色时，安装程序会询问该服务器在Internet上被访问时使用的FQDN名称，并且会自动使用该名称为CAS上所有的基于IIS的服务配置ExternalURL属性，这些服务包括：Outlook Web App、Exchange Control Panel、ActiveSync、Offline Address Book、Exchange Web Service、AutoDiscover等，并且在启用Outlook Anywhere功能时，会再次询问FQDN名称。</p>
<p>因此，在Exchange 2010中，基本上不需要专门关心这些服务的ExternalURL是否正确。这是与Exchange 2007相比很大的改进。当然，也可以对这些属性进行检查和修改。通过Exchange Management Console图形工具，可以修改OWA、ECP、OAB、Outlook Anywhere以及ActiveSync的URL属性；而对于Exchange Web Service，就必须使用Exchange Management Shell命令行工具进行修改了。</p>
<p>命令都是以Get-<em>SERVICE</em>VirtualDirectoy和Set-<em>SERVICE</em>VirtualDirectoy来实现的，其中的<em>SERVICE</em>是具体的服务名称。例如对于OWA，就是Get-OWAVirtualDirectoy；对于Web Service，就是Get-WebServicesVirtualDirectoy。</p>
<p>具体的使用情况就不再赘述了，需要注意的是Set命令中的Identity参数，这个参数直接输入比较困难，需要指定服务器名和站点名，而且站点名中带有空格，需要把参数用引号引起来。因此可以通过Get命令先获取，然后通过管道符传递给Set命令。以下是获取并修改Web Service URL的命令。</p>
<p>以下示例中，第一条命令用于获取；第二条命令先Get再Set；第3条命令直接指定需要修改的对象标识。</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/48.png"><img title="4" src="http://fesd77.files.wordpress.com/2011/01/4_thumb8.png?w=968&amp;h=184" alt="4" width="700" height="133" border="0" /></a></p>
<p><strong>创建额外的AutoDiscover发布点</strong></p>
<p>在Exchange客户端访问服务器安装完成后，会自动在IIS中创建一个名为AutoDiscover的虚拟目录，客户端可以通过对该虚拟目录的访问获取自动发现的配置信息。在某些情况下，需要将AutoDiscover服务入口点与其它访问入口分开，此时就需要创建额外的AutoDiscover虚拟目录来满足要求了。</p>
<p>某些情况指的是：1、主站点普通Web访问流量较大；2、主站点承载了电子邮件流量较大。管理员可以根据实际的运行情况来判断是否需要额外创建AutoDiscover发布。</p>
<p>创建额外的AutoDiscover发布之前，需要在Exchange客户端访问服务器的IIS中创建额外的Web站点，然后利用New-AutodiscoverVirtualDirectory命令进行创建，完整的命令是：<br />
New-AutodiscoverVirtualDirectory -Websitename<span style="font-size: medium;"><span style="color: #333333;"><span style="font-family: Georgia;"> <em>&lt;websitename&gt;</em> -BasicAuthentication:$true -WindowsAuthentication:$true</span></span></span></p>
<p><strong>利用Outlook客户端检查自动发现配置</strong></p>
<p>在Outlook运行后，在Windows的系统托盘区，会出现一个Outlook图标，按住Ctrl键并用鼠标点击这个图标，在弹出窗口中，可以看到Test E-mail AutoConfiguration菜单项，点击后就可以进行自动配置的检查。</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/63.png"><img title="6" src="http://fesd77.files.wordpress.com/2011/01/6_thumb3.png?w=426&amp;h=233" alt="6" width="426" height="233" border="0" /></a></p>
<p>输入电子邮件地址和密码后，点击Test后，Outlook就开始检索自动发现服务。可以从Log中查看Outlook检索服务时的顺序：</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/75.png"><img title="7" src="http://fesd77.files.wordpress.com/2011/01/7_thumb5.png?w=668&amp;h=456" alt="7" width="668" height="456" border="0" /></a></p>
<p>自动发现检索成功后，可以从Results和XML中分别看到AutoDiscover的结果。在XML中看到的，就是从服务器上获取的autodiscover.xml文件的原始数据。</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/94.png"><img title="9" src="http://fesd77.files.wordpress.com/2011/01/9_thumb4.png?w=668&amp;h=456" alt="9" width="668" height="456" border="0" /></a></p>
<p>Results中看到的，是根据autodiscover.xml文件的数据解读出的配置信息。</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/85.png"><img title="8" src="http://fesd77.files.wordpress.com/2011/01/8_thumb5.png?w=668&amp;h=456" alt="8" width="668" height="456" border="0" /></a></p>
<p>注意里面的一些URL路径，例如OOF、OAB、Availability Service等。Outlook客户端需要使用这些功能时，都会去访问这些URL。如果这些URL不可用，即使邮件访问正常，Outlook也会弹出错误信息，例如“服务不可用”“未能找到对象”“服务器URL不存在”等。</p>
<p><strong>利用命令行工具检查</strong></p>
<p>也可以通过Exchange Management Shell中的Test-OutlookWebServices命令来检查AutoDiscover中配置信息是否有效。</p>
<p>可以直接运行Test-OutlookWebServices，此时Exchange会使用一个名为extest_3e2af001155e4的帐号进行测试。管理员可以预先创建出这个用户邮箱。</p>
<p>也可以在进行测试时输入参数，来指定用于测试的用户邮箱以及客户端访问服务器名称，例如：<br />
Test-OutlookWebServices -Identity GeorgeWu -ClientAccessServer pcoeexchhtcas1</p>
<p>命令会检查Outlook连接时使用到的各个Exchange服务，命令输出结果很长，就不做截图了。</p>
<p>另外一个相关的命令是Test-OutlookConnectivity，这个命令可以通过Protocol参数来检查MAPI和HTTPS两种连接方式的可用状态。这个命令如果没有指定用户信息，会使用一个名为extest_81a4a2b331c84的帐号：</p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/a4.png"><img title="A" src="http://fesd77.files.wordpress.com/2011/01/a_thumb4.png?w=956&amp;h=283" alt="A" width="700" height="207" border="0" /></a></p>
<p><strong>利用Microsoft提供的分析工具</strong></p>
<p>Microsoft提供了Exchange远程连接分析器，这个分析器可以对与Exchange相关的所有外部访问进行测试，可以说，这是个“一网打尽”的部署检查工具。</p>
<p>通过浏览器直接访问以下站点即可：</p>
<p><a style="color: #0066cc;" title="https://www.testexchangeconnectivity.com/" href="https://www.testexchangeconnectivity.com/"><span style="font-family: Georgia; font-size: medium;">https://www.testexchangeconnectivity.com/</span></a></p>
<p><a style="color: #0066cc;" href="http://fesd77.files.wordpress.com/2011/01/b4.png"><span style="font-family: Georgia; font-size: medium;"><img title="B" src="http://fesd77.files.wordpress.com/2011/01/b_thumb3.png?w=862&amp;h=686" alt="B" width="700" height="557" border="0" /></span></a></p>
<p>使用也很简单，唯一要注意的是，如果Exchange服务器上的证书是通过自建的证书颁发机构颁发的，在进行分析时，需要在检测是勾选“忽略对SSL的信任”（“Ignore Trust for SSL”）</p>
<p><a style="color: #ff4b33;" href="http://fesd77.files.wordpress.com/2011/01/c3.png"><img title="C" src="http://fesd77.files.wordpress.com/2011/01/c_thumb3.png?w=860&amp;h=687" alt="C" width="700" height="559" border="0" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1529</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exchange Web Service (EWS) API 使用笔记</title>
		<link>https://www.softwareace.cn/?p=803</link>
		<comments>https://www.softwareace.cn/?p=803#comments</comments>
		<pubDate>Tue, 13 May 2014 01:36:35 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=803</guid>
		<description><![CDATA[有时候我们需要使用程序来进行收发邮件, 传统的POP3/SMTP/IMAP等协议也正广泛的被使用着,有关这些协 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>有时候我们需要使用程序来进行收发邮件, 传统的POP3/SMTP/IMAP等协议也正广泛的被使用着,有关这些协议的收发邮件代码网上一抓一大把~ 如果要用这些协议可以去别处看看.</p>
<p>我这里要谈的是使用Microsoft Exchange Sever来进行邮件的收发.</p>
<p>通过网上查找资料我找到了微软官方的<a href="http://msdn.microsoft.com/en-us/exchange/default.aspx">Exchange Server Developer Center</a>, 从中得知了可以使用Microsoft Exchange Web Services Managed API来进行Exchange Server的交互. 你可以在<a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1" target="_blank">这里</a>下载到当前的最新1.1版本.</p>
<p>下载时有两个文件,根据你的实际情况选择即可:</p>
<blockquote><p>Instructions<br />
For x64 (64-bit) computers, download and run EwsManagedApi.msi<br />
For x86 (32-bit) computers, download and run EwsManagedApi32.msi</p></blockquote>
<p>安装之后的安装目录如图:</p>
<p><a href="http://liaodd.me/blog/wp-content/uploads/2010/11/image.png"><img title="image" alt="image" src="http://liaodd.me/blog/wp-content/uploads/2010/11/image_thumb.png" width="411" height="231" border="0" /></a></p>
<p>要使用EWS, 你需要将Microsoft.Exchange.WebServices.dll引用到你的项目之中.</p>
<p>一些基本的使用可以阅读GettingStarted.doc文件,里面说的比较清楚.</p>
<p>英文不好的同学可以查看这些篇文章</p>
<blockquote><p><a href="http://www.cnblogs.com/diaojia/archive/2010/10/19/1855839.html" target="_blank">EWS Managed API 介绍(上)</a></p>
<p><a href="http://www.cnblogs.com/diaojia/archive/2010/10/20/1856995.html" target="_blank">EWS Managed API 介绍(下)</a></p></blockquote>
<p>来自博客园的这两篇文章基本是对于官方GettingStarted.doc文件的翻译.</p>
<p>&nbsp;</p>
<p>但是在我的应用中, 我需要读取所有在Inbox(收件箱)里的新邮件, 而已读邮件将被我忽略掉, 在读到新邮件后经过处理再将其标记为已读. 在示例代码中给出的读取Inbox中的邮件功能显然不能满足我的要求.</p>
<p>经过调研,写出如下代码已实现目标</p><pre class="crayon-plain-tag">//ExchangeService版本为2007SP1  
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);  
//参数是用户名,密码,域  
service.Credentials = new WebCredentials(Info.UserName, Info.Password, Info.Domain);  
//给出Exchange Server的URL http://xxxxxxx  
service.Url = new Uri(Info.SeverUrl);  
//你自己的邮件地址 xxx@xxx.xxx  
service.AutodiscoverUrl(Info.Email);  
//创建过滤器, 条件为邮件未读.  
SearchFilter sf = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);  
//查找Inbox,加入过滤器条件,结果10条  
FindItemsResults&lt;item&gt; findResults = service.FindItems(  
    WellKnownFolderName.Inbox,  
    sf,  
    new ItemView(10));  

foreach (Item item in findResults.Items)  
{  
    EmailMessage email = EmailMessage.Bind(service, item.Id);  
    if (!email.IsRead)  
    {  
        Console.WriteLine(email.Body);  
        //标记为已读  
        email.IsRead = true;  
        //将对邮件的改动提交到服务器  
        email.Update(ConflictResolutionMode.AlwaysOverwrite);  
    }  
}&lt;/item&gt;</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=803</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>贝叶斯算法(bayesian)在反垃圾邮件中的应用</title>
		<link>https://www.softwareace.cn/?p=799</link>
		<comments>https://www.softwareace.cn/?p=799#comments</comments>
		<pubDate>Tue, 06 May 2014 10:06:15 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=799</guid>
		<description><![CDATA[一、 贝叶斯反垃圾邮件技术介绍 贝叶斯是基于概率的一种算法，是Thomas Bayes：一位伟大的数学大师所创 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>一、 贝叶斯<a href="http://www.hz263.cn/youshi/27.html">反垃圾邮件</a>技术介绍<br />
贝叶斯是基于概率的一种算法，是Thomas Bayes：一位伟大的数学大师所创建的，目前此种算法用于过滤垃圾邮件得到了广泛地好评。贝叶斯过滤器是基于“自我学习”的智能技术，能够使自己适应垃圾邮件制造者的新把戏，同时为合法电子邮件提供保护。在智能邮件过滤技术中，贝叶斯（Bayesian）过滤技术取得了较大的成功，被越来越多地应用在<a href="http://www.hz263.cn/youshi/27.html">反垃圾邮件</a>的产品中。<br />
二、 贝叶斯过滤算法的基本步骤</p>
<p>1. 收集大量的垃圾邮件和非垃圾邮件，建立垃圾邮件集和非垃圾邮件集。<br />
2. 提取邮件主题和邮件体中的独立字符串，例如 ABC32，￥234等作为TOKEN串并统计提取出的TOKEN串出现的次数即字频。按照上述的方法分别处理垃圾邮件集和非垃圾邮件集中的所有邮件。<br />
3. 每一个邮件集对应一个哈希表，hashtable_good对应非垃圾邮件集而hashtable_bad对应垃圾邮件集。表中存储TOKEN串到字频的映射关系。<br />
4. 计算每个哈希表中TOKEN串出现的概率P=（某TOKEN串的字频）/（对应哈希表的长度）<br />
5. 综合考虑hashtable_good和hashtable_bad，推断出当新来的邮件中出现某个TOKEN串时，该新邮件为垃圾邮件的概率。数学表达式为：<br />
A 事件 &#8212;- 邮件为垃圾邮件；<br />
t1,t2 …….tn 代表 TOKEN 串<br />
则 P （ A|ti ）表示在邮件中出现 TOKEN 串 ti 时，该邮件为垃圾邮件的概率。<br />
设<br />
P1 （ ti ） = （ ti 在 hashtable_good 中的值）<br />
P2 （ ti ） = （ ti 在 hashtable_ bad 中的值）<br />
则 P （ A|ti ） =P2 （ ti ） /[ （ P1 （ ti ） +P2 （ ti ） ] ；</p>
<p>6. 建立新的哈希表hashtable_probability存储TOKEN串ti到P（A|ti）的映射<br />
7. 至此，垃圾邮件集和非垃圾邮件集的学习过程结束。根据建立的哈希表 hashtable_probability可以估计一封新到的邮件为垃圾邮件的可能性。<br />
当新到一封邮件时，按照步骤2，生成TOKEN串。查询hashtable_probability得到该TOKEN 串的键值。<br />
假设由该邮件共得到N个TOKEN 串，t1,t2…….tn,hashtable_probability中对应的值为 P1 ， P2 ， ……PN ， P(A|t1 ,t2, t3……tn) 表示在邮件中同时出现多个TOKEN串t1,t2……tn时，该邮件为垃圾邮件的概率。<br />
由复合概率公式可得<br />
P(A|t1 ,t2, t3……tn)=（P1*P2*……PN）/[P1*P2*……PN+（1-P1）*（1-P2）*……（1-PN）]<br />
当 P(A|t1 ,t2, t3……tn) 超过预定阈值时，就可以判断邮件为垃圾邮件。</p>
<p>三、 贝叶斯过滤算法举例<br />
例如：一封含有 “ 法无效字符轮无效字符功 ” 字样的垃圾邮件 A 和一封含有 “ 法无效字符律 ” 字样的非垃圾邮件 B 。 根据邮件 A 生成 hashtable_bad ，该哈希表中的记录为<br />
法： 1 次<br />
无效字符轮： 1 次<br />
无效字符功： 1 次<br />
计算得在本表中：<br />
无效字符法出现的概率为 0.3<br />
无效字符轮出现的概率为 0.3<br />
无效字符功出现的概率为 0.3<br />
根据邮件B生成hashtable_good，该哈希表中的记录为：<br />
法： 1 次<br />
律： 1 次<br />
计算得在本表中：<br />
法出现的概率为 0.5<br />
律出现的概率为 0.5<br />
综合考虑两个哈希表，共有四个 TOKEN 串：法无效字符论无效字符功无效字符律<br />
当邮件中出现“法”时，该邮件为垃圾邮件的概率为：<br />
P = 0.3/ （ 0.3 + 0.5 ） = 0.375<br />
出现“无效字符轮”时，该邮件为垃圾邮件的概率为：<br />
P = 0.3/ （ 0.3 + 0 ） = 1<br />
出现“无效字符功”时，该邮件为垃圾邮件的概率为：<br />
P = 0.3/ （ 0.3 + 0 ） = 1<br />
出现“无效字符律”时，该邮件为垃圾邮件的概率为：<br />
P = 0/ （ 0 + 0.5 ） = 0<br />
由此可得第三个哈希表 hashtable_probability ，其数据为：<br />
无效字符法： 0.375<br />
无效字符轮： 1<br />
无效字符功： 1<br />
律： 0<br />
当新到一封含有“功无效字符律”的邮件时，我们可得到两个TOKEN串：功 律<br />
查询哈希表 hashtable_probability 可得：<br />
P （垃圾邮件 | 功） = 1<br />
P （垃圾邮件 | 律） = 0<br />
此时该邮件为垃圾邮件的可能性为：<br />
P= （ 0*1 ） /[0*1+ （ 1-0 ） * （ 1-1 ） ] = 0<br />
由此可推出该邮件为非垃圾邮件。<br />
四、总结<br />
叶斯过滤器为什么能够工作得这么好呢？因为贝叶斯过滤器纯粹根据统计学规律运作，比起那些需要分析邮件句法或内容含义的过滤器来显然要简单的多，而且可计算性强得多。更重要的是，这些标记完全可以由用户根据自己所接收的垃圾邮件和非垃圾邮件来创建，因而可以获得一种对用户来说独一无二的过滤器。这意味着垃圾邮件发送者根本无法猜测出你的过滤器是如何配置的，从而有效地阻截住各类垃圾邮件。<br />
不过，尽管贝叶斯过滤器非常有效，但它仍需要进行优化才能真正完美。比如它可以结合 “白名单”降低误报率，结合“黑名单”降低漏过率，还可以利用其他技术如源址认证使其成为更加精确的垃圾邮件过滤器。</p>
<p>相信很多关注反<a href="http://www.youjianqunfa.net/" target="_blank">垃圾邮件</a>的朋友都听说过贝叶斯过滤算法，但是对于贝叶斯过滤算法是如何过滤<a href="http://www.youjianqunfa.net/" target="_blank">垃圾邮件</a>却不是很了解，<a href="http://www.youjianqunfa.net/" target="_blank">邮件群发网</a>在此就列出它的过滤步骤，如下：</p>
<p>1.收集大量的垃圾邮件和非垃圾邮件，建立不同的集。</p>
<p>2.提取邮件主题和邮件体中的独立字串，然后获取频率。按照上述的方法分别处理垃圾邮件集和非垃圾邮件集中的所有邮件。</p>
<p>3.每一个<a href="http://www.youjianqunfa.net/" target="_blank">邮件</a>集对应一个哈希表，hashtable_good对应非垃圾邮件集而hashtable_bad对应垃圾邮件集。</p>
<p>4.计算每个哈希表中关键字符串出现的概率P=（某字频）/（对应哈希表的长度）</p>
<p>5.综合考虑hashtable_good和hashtable_bad，推断出当新邮件中出现某个字串时，该新邮件为垃圾邮件的概率。</p>
<p>6.建立新的哈希表 hashtable_probability</p>
<p>7.至此，垃圾邮件集和非<a href="http://www.youjianqunfa.net/" target="_blank">垃圾邮件</a>集的学习过程结束。根据建立的哈希表 hashtable_probability可以估计一封新到的邮件为垃圾邮件的可能性。</p>
<p>在今天的反垃圾邮件技术中，则融合了以前大部分实用技术的精华，采用权重算法让判断垃圾邮件的工作更精确、更智能。但保守的人们还是不愿把规则设置的过严，因为没有任何一个用户希望把自己正规的邮件当作垃圾邮件处理掉。本文来源于网络。</p>
<p>贝叶斯过滤是根据贝叶斯准则和贝叶斯定理，以已知垃圾邮件和非垃圾邮件为样本，来判断下一封邮件是垃圾邮件的概率的技术。跟普通的内容过滤技术不 同，贝叶斯过滤特征的来源比较多，可以采用邮件正文单词、邮件头信息（发送者、传递路径等）、邮件的HTML编码等作为判断的特征元素，因此对垃圾邮件的 判断能够做到更全面、更准确。更重要的是，贝叶斯过滤还具有自学习功能，能够学习分辨垃圾邮件与非邮件之间的差别，差别是用概率来表示的，并且自动应用到 以后的检测中。在收到几百封信件后，一个好的贝叶斯过滤器就可以自动识别各种垃圾邮件。<br />
使用贝叶斯算法来进行垃圾邮件过滤的基本步骤是：<br />
1．收集样本垃圾邮件和非垃圾邮件，建立垃圾邮件集和非垃圾邮件集；<br />
2．在垃圾邮件集和非垃圾邮件集中，提取特征来源中的独立字符串abc，并统计该字符串出现的次数（字频）；针对垃圾邮件集和非垃圾邮件集，分别建立哈希表hash_spam和hash_normal，在哈希表中存储特征字符串abc字频的映射关系；<br />
3．计算每个哈希表中特征字符串abc出现的概率P=（该特征字符串的字频）/（对应哈希表的长度）；<br />
4．综合考虑hash_spam和hash_normal，推断当新接收的邮件中出现特征字符串abc时，该新邮件为垃圾邮件的概率。<br />
如果：A事件 邮件为垃圾邮件；t1，t2 …….tn代表特征字符串；则P（Ati）表示在邮件中出现TOKEN串ti时，该邮件为垃圾邮件的概率。<br />
设P1(ti)=ti在hash_spam中的值；P2(ti)=ti在hash_normal中的值；则P(Ati)=P2(ti)/[(P1(ti)+P2(ti)) ；<br />
5．建立新的哈希表hash_probability存储特征字符串ti到P（Ati）的映射；<br />
6．根据建立的哈希表hash_probability可以估计一封新到的邮件为垃圾邮件的可能性。<br />
这样，当接收到一个邮件时，首先按照步骤2生成特征字符串。查询hash_probability得到该字符串的键值。假设由该邮件共得到N个特征字符 串t1，t2…….tn，hashtable_probability中对应的值为P1，P2……PN，P（At1，t2，t3……tn）表示在邮件中同 时出现多个字符串t1，t2……tn时，该邮件为垃圾邮件的概率。<br />
由复合概率公式可得：<br />
P（At1,t2,t3……tn）=（P1*P2*……PN）/[P1*P2*……PN+（1-P1）*（1-P2）*……（1-PN）]<br />
当P（At1,t2,t3……tn）超过预定阀值时，就可以判断邮件为垃圾邮件。　　当新邮件到达的时候，就通过贝叶斯过滤器分析，通过使用各个特征来计算邮件是垃圾邮件的概率。通过不断的分析，过滤器也不断地获得自更新。如果通过各种特征判断一个包含单词abc的邮件是垃圾邮件，那么单词abc成为垃圾邮件特征的概率就增加了。<br />
这样，贝叶斯过滤器就有了自适应能力，既能自动进行，也可以用户手工操作，也就更能适应单个用户的使用。而垃圾邮件发送者要获得这样的适应能力就很难 了，因此，很难逃避过滤器的过滤。当然他们还是能够将邮件伪装成很普通的正常邮件样子的。比如，垃圾邮件发送者能去对某个人的过滤器进行判断；又比如，采 用发送回执的办法来了解哪些邮件被用户打开了等，这样他们就可以适应过滤器了。<br />
设计优良的贝叶斯过滤器，可以识别99.7%以上的垃圾邮件，而且误判率极低，是目前最有效的反垃圾邮件技术。这主要是因为贝叶斯过滤具有以下特点。<br />
贝叶斯过滤技术对邮件的所有内容进行分析，不仅仅是其中的某个关键词，而且它能判别邮件是垃圾邮件还是正常邮件。例如：包含&#8221;free&#8221;&#8221;cash&#8221;&#8221; 发票&#8221;字样的邮件不一定是垃圾邮件，如果采用关键字过滤技术，显然难以达到理想的效果。而贝叶斯过滤技术既考虑了这些词在垃圾邮件中出现的概率、又考虑了 它在正常邮件中的概率，综合考虑这些因素做出判断。可以说，贝叶斯过滤技术具有一定的智能，它对邮件中的关键词能综合地进行评判，可以把握&#8221;好&#8221;与&#8221;坏&#8221; 之间的平衡。显然，这种技术远远高于非1即0的静态过滤技术。<br />
贝叶斯过滤技术具备自适应功能，通过学习新的垃圾邮件及正常邮件样本，它 将能对抗最新的垃圾邮件，并且对变体字有奇效。比如，垃圾邮件发送者开始使用&#8221;f-r-e-e&#8221;来代替&#8221;free&#8221;这样能够绕过关键字检查，除非&#8221;f- r-e-e&#8221;被加到新的关键字中。而对贝叶斯过滤技术而言，当它发现邮件中含有&#8221;f-r-e-e&#8221;时，由于正常邮件中从来没有发现这个词，因此它是垃圾邮 件的可能性将急剧增加，&#8221;f-r-e-e&#8221;这个新词无疑成了垃圾邮件的指示器。再比如，垃圾邮件中用5ex代替sex，贝叶斯过滤技术也可推算出它是垃圾 邮件的可能性也急剧增加。<br />
贝叶斯过滤技术更加个性化。它能学习并理解用户对邮件的偏好。如前所述，&#8221;mortgage&#8221;抵押一词对软件公司而言意味着垃圾，但对金融类公司则意味着邮件。贝叶斯过滤技术能根据用户的这种偏好进行处理。<br />
贝叶斯过滤技术支持多语种或者说与编码无关。这是因为它分析的是字串，无论是数字、词、符号、还是别的什么，当然与语言无关。<br />
贝叶斯过滤器很难被欺骗。垃圾邮件发送高手通常通过减少垃圾词汇（如free、viagra、发票）或者在信中多加入一些好的词汇（如合同、文件）来绕 过一般的邮件内容检查，但由于贝叶斯过滤技术具有个性化的色彩，要想成功地绕过它的检查，就不得不对每个收件人的偏好进行研究，这简直是&#8221;不可能完成的任 务&#8221;，垃圾邮件发送者是无法容忍的。若采用变化字，则如前所述，贝叶斯过滤技术判断其为垃圾邮件的可能性反而增加。<br />
实践也证明，贝叶斯过滤器在用户端和服务器中效果是非常明显的，如优秀的贝叶斯过滤器能够识别超过99.9%的垃圾邮件。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=799</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>贝叶斯算法&#8211;邮件过滤</title>
		<link>https://www.softwareace.cn/?p=798</link>
		<comments>https://www.softwareace.cn/?p=798#comments</comments>
		<pubDate>Tue, 06 May 2014 09:40:18 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=798</guid>
		<description><![CDATA[贝叶斯是基于概率的一种算法，是Thomas Bayes：一位伟大的数学大师所创建的，目前此种算法用于过滤垃圾邮 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>贝叶斯是基于概率的一种算法，是Thomas Bayes：一位伟大的数学大师所创建的，目前此种算法用于过滤垃圾邮件得到了广泛地好评。贝叶斯过滤器是基于“自我学习”的智能技术，能够使自己适应垃 圾邮件制造者的新把戏，同时为合法电子邮件提供保护。在智能邮件过滤技术中，贝叶斯(Bayesian)过滤技术取得了较大的成功，被越来越多地应用在反垃圾邮件的产品中。<br />
二、  贝叶斯过滤算法的基本步骤<br />
1. 收集大量的垃圾邮件和非垃圾邮件，建立垃圾邮件集和非垃圾邮件集。</p>
<p>2. 提取邮件主题和邮件体中的独立字符串，例如 ABC32，￥234等作为TOKEN串并统计提取出的TOKEN串出现的次数即字频。按照上述的方法分别处理垃圾邮件集和非垃圾邮件集中的所有邮件。</p>
<p>3. 每一个邮件集对应一个哈希表，hashtable_good对应非垃圾邮件集而hashtable_bad对应垃圾邮件集。表中存储TOKEN串到字频的映射关系。</p>
<p>4. 计算每个哈希表中TOKEN串出现的概率P=(某TOKEN串的字频)/(对应哈希表的长度)<br />
5. 综合考虑hashtable_good和hashtable_bad，推断出当新来的邮件中出现某个TOKEN串时，该新邮件为垃圾邮件的概率。数学表达式为：<br />
A 事件 &#8212;- 邮件为垃圾邮件；<br />
t1,t2 …….tn 代表 TOKEN 串<br />
则 P ( A|ti )表示在邮件中出现 TOKEN 串 ti 时，该邮件为垃圾邮件的概率。<br />
设<br />
P1 ( ti ) = ( ti 在hashtable_good 中的值)<br />
P2 ( ti ) = ( ti 在 hashtable_bad 中的值)<br />
则 P ( A|ti )=P2 ( ti ) /[ ( P1 ( ti ) +P2 ( ti ) ] ；<br />
6. 建立新的哈希表hashtable_probability存储TOKEN串ti到P(A|ti)的映射<br />
7. 至此，垃圾邮件集和非垃圾邮件集的学习过程结束。根据建立的哈希表 hashtable_probability可以估计一封新到的邮件为垃圾邮件的可能性。<br />
当新到一封邮件时，按照步骤2，生成TOKEN串。查询hashtable_probability得到该TOKEN 串的键值。<br />
假设由该邮件共得到N个TOKEN 串，t1,t2…….tn,hashtable_probability中对应的值为 P1 ， P2 ， ……PN ， P(A|t1 ,t2,t3……tn) 表示在邮件中同时出现多个TOKEN串t1,t2……tn时，该邮件为垃圾邮件的概率。<br />
由复合概率公式可得<br />
P(A|t1 ,t2, t3……tn)=(P1*P2*……PN)/[P1*P2*……PN+(1-P1)*(1-P2)*……(1-PN)]<br />
当 P(A|t1 ,t2,t3……tn) 超过预定阈值时，就可以判断邮件为垃圾邮件。<br />
三、  贝叶斯过滤算法举例<br />
例如：一封含有 “ 法(faint，csdn也有屏蔽！)轮(faint，csdn也有屏蔽！)功” 字样的垃圾邮件 A 和一封含有 “ 法律 ” 字样的非垃圾邮件 B 。 根据邮件 A 生成hashtable_bad ，该哈希表中的记录为<br />
法： 1 次<br />
轮： 1 次<br />
功： 1 次<br />
计算得在本表中：<br />
法出现的概率为 0.3<br />
轮出现的概率为 0.3<br />
功出现的概率为 0.3<br />
根据邮件B生成hashtable_good，该哈希表中的记录为：<br />
法： 1 次<br />
律： 1 次<br />
计算得在本表中：<br />
法出现的概率为 0.5<br />
律出现的概率为 0.5<br />
综合考虑两个哈希表，共有四个TOKEN 串：法 轮功 律<br />
当邮件中出现“法”时，该邮件为垃圾邮件的概率为：<br />
P = 0.3/ ( 0.3 + 0.5 ) = 0.375<br />
出现“轮”时，该邮件为垃圾邮件的概率为：<br />
P = 0.3/ ( 0.3 + 0 ) = 1<br />
出现“功”时，该邮件为垃圾邮件的概率为：<br />
P = 0.3/ ( 0.3 + 0 ) = 1<br />
出现“律”时，该邮件为垃圾邮件的概率为：<br />
P = 0/ ( 0 + 0.5 ) = 0<br />
由此可得第三个哈希表hashtable_probability ，其数据为：<br />
法： 0.375<br />
轮： 1<br />
功： 1<br />
律： 0<br />
当新到一封含有“功律”的邮件时，我们可得到两个TOKEN串：功 律<br />
查询哈希表hashtable_probability 可得：<br />
P (垃圾邮件 | 功) = 1<br />
P (垃圾邮件 | 律) = 0<br />
此时该邮件为垃圾邮件的可能性为：<br />
P= ( 0*1 ) /[0*1+ ( 1-0 ) * ( 1-1 ) ] = 0<br />
由此可推出该邮件为非垃圾邮件。<br />
四、  总结<br />
叶斯过滤器为什么能够工作得这么好呢？因为贝叶斯过滤器纯粹根据统计学规律运作，比起那些需要分析邮件句法或内容含义的过滤器来显然要简单的多，而且可计算性强得多。更重要的是，这些标记完全可以由用户根据自己所接收的垃圾邮件和非垃圾邮件来创建，因而可以获得一种对用户来说独一无二的过滤器。这意味着垃圾邮件发送者根本无法猜测出你的过滤器是如何配置的，从而有效地阻截住各类垃圾邮件。<br />
不过，尽管贝叶斯过滤器非常有效，但它仍需要进行优化才能真正完美。比如它可以结合 “白名单”降低误报率，结合“黑名单”降低漏过率，还可以利用其他技术如源址认证使其成为更加精确的垃圾邮件过滤器。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=798</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>贝叶斯过滤算法</title>
		<link>https://www.softwareace.cn/?p=797</link>
		<comments>https://www.softwareace.cn/?p=797#comments</comments>
		<pubDate>Tue, 06 May 2014 09:32:09 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=797</guid>
		<description><![CDATA[朴素贝叶斯分类是一种十分简单的分类算法，叫它朴素贝叶斯分类是因为这种方法的思想真的很朴素，朴素贝叶斯的思想基础 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>朴素贝叶斯分类是一种十分简单的分类算法，叫它朴素贝叶斯分类是因为这种方法的思想真的很朴素，朴素贝叶斯的思想基础是这样的：对于给出的待分类项，求解在此项出现的条件下各个类别出现的概率，哪个最大，就认为此待分类项属于哪个类别。通俗来说，就好比这么个道理，你在街上看到一个黑人，我问你你猜这哥们哪里来的，你十有八九猜非洲。为什么呢？因为黑人中非洲人的比率最高，当然人家也可能是美洲人或亚洲人，但在没有其它可用信息下，我们会选择条件概率最大的类别，这就是朴素贝叶斯的思想基础，维基百科上的词条<a title="http://zh.wikipedia.org/wiki/%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%AE%9A%E7%90%86" href="http://zh.wikipedia.org/wiki/%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%AE%9A%E7%90%86">http://zh.wikipedia.org/wiki/%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%AE%9A%E7%90%86</a> 。</p>
<p>朴素贝叶斯分类的正式定义如下：</p>
<p>1、设<img title="x=\{a_1,a_2,...,a_m\}" alt="" src="http://latex.codecogs.com/gif.latex?x=%5C%7Ba_1,a_2,...,a_m%5C%7D" />为一个待分类项，而每个a为x的一个特征属性。</p>
<p>2、有类别集合<img title="C=\{y_1,y_2,...,y_n\}" alt="" src="http://latex.codecogs.com/gif.latex?C=%5C%7By_1,y_2,...,y_n%5C%7D" />。</p>
<p>3、计算<img title="P(y_1|x),P(y_2|x),...,P(y_n|x)" alt="" src="http://latex.codecogs.com/gif.latex?P(y_1%7Cx),P(y_2%7Cx),...,P(y_n%7Cx)" />。</p>
<p>4、如果<img title="P(y_k|x)=max\{P(y_1|x),P(y_2|x),...,P(y_n|x)\}" alt="" src="http://latex.codecogs.com/gif.latex?P(y_k%7Cx)=max%5C%7BP(y_1%7Cx),P(y_2%7Cx),...,P(y_n%7Cx)%5C%7D" />，则<img title="x \in y_k" alt="" src="http://latex.codecogs.com/gif.latex?x%20%5Cin%20y_k" />。</p>
<p>那么现在的关键就是如何计算第3步中的各个条件概率。我们可以这么做：</p>
<p>1、找到一个已知分类的待分类项集合，这个集合叫做训练样本集。</p>
<p>2、统计得到在各类别下各个特征属性的条件概率估计。即<img title="点击查看原始大小图片" alt="" src="http://latex.codecogs.com/gif.latex?P(a_1%7Cy_1),P(a_2%7Cy_1),...,P(a_m%7Cy_1);P(a_1%7Cy_2),P(a_2%7Cy_2),...,P(a_m%7Cy_2);...;P(a_1%7Cy_n),P(a_2%7Cy_n),...,P(a_m%7Cy_n)" width="700" height="17" />。</p>
<p>3、如果各个特征属性是条件独立的，则根据贝叶斯定理有如下推导：</p>
<p><img title="P(y_i|x)=\frac{P(x|y_i)P(y_i)}{P(x)}" alt="" src="http://latex.codecogs.com/gif.latex?P(y_i%7Cx)=%5Cfrac%7BP(x%7Cy_i)P(y_i)%7D%7BP(x)%7D" /></p>
<p>因为分母对于所有类别为常数，因为我们只要将分子最大化皆可。又因为各特征属性是条件独立的，所以有：</p>
<p><img title="P(x|y_i)P(y_i)=P(a_1|y_i)P(a_2|y_i)...P(a_m|y_i)P(y_i)=P(y_i)\prod^m_{j=1}P(a_j|y_i)" alt="" src="http://latex.codecogs.com/gif.latex?P(x%7Cy_i)P(y_i)=P(a_1%7Cy_i)P(a_2%7Cy_i)...P(a_m%7Cy_i)P(y_i)=P(y_i)%5Cprod%5Em_%7Bj=1%7DP(a_j%7Cy_i)" /></p>
<p>根据上述分析，朴素贝叶斯分类的流程可以由下图表示（暂时不考虑验证）：</p>
<p><img alt="" src="http://images.cnblogs.com/cnblogs_com/leoo2sk/WindowsLiveWriter/4f6168bb064a_9C14/1_thumb.png" width="717" height="557" /></p>
<p>可以看到，整个朴素贝叶斯分类分为三个阶段：</p>
<p>第一阶段——准备工作阶段，这个阶段的任务是为朴素贝叶斯分类做必要的准备，主要工作是根据具体情况确定特征属性，并对每个特征属性进行适当划分，然后由人工对一部分待分类项进行分类，形成训练样本集合。这一阶段的输入是所有待分类数据，输出是特征属性和训练样本。这一阶段是整个朴素贝叶斯分类中唯一需要人工完成的阶段，其质量对整个过程将有重要影响，分类器的质量很大程度上由特征属性、特征属性划分及训练样本质量决定。</p>
<p>第二阶段——分类器训练阶段，这个阶段的任务就是生成分类器，主要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率估计，并将结果记录。其输入是特征属性和训练样本，输出是分类器。这一阶段是机械性阶段，根据前面讨论的公式可以由程序自动计算完成。</p>
<p>第三阶段——应用阶段。这个阶段的任务是使用分类器对待分类项进行分类，其输入是分类器和待分类项，输出是待分类项与类别的映射关系。这一阶段也是机械性阶段，由程序完成。</p>
<p>&nbsp;</p>
<p>现在介绍一个<a title="https://github.com/joelmartinez/nBayes/wiki" href="https://github.com/joelmartinez/nBayes/wiki">nBayes</a>项目，很容易在应用程序中引入基于统计决策。</p>
<p>&nbsp;</p>
<p>下面是收集的几篇文章介绍贝叶斯算法：</p>
<p><a href="http://www.cnblogs.com/leoo2sk/archive/2010/09/17/naive-bayesian-classifier.html">算法杂货铺——分类算法之朴素贝叶斯分类(Naive Bayesian classification)</a></p>
<p><a href="http://www.cnblogs.com/wufawei/archive/2012/04/11/2441615.html">贝叶斯推断及其互联网应用（一）</a></p>
<p><a href="http://www.cnblogs.com/wufawei/archive/2012/04/11/2441619.html">贝叶斯推断及其互联网应用（二）</a></p>
<p><a href="http://www.cnblogs.com/chenying99/archive/2012/04/21/2460838.html">详解：贝叶斯算法(bayesian)在GCMail反垃圾邮件系统中的应用</a></p>
<p><a href="http://songshuhui.net/archives/62770">死理性派是怎样判断漂亮女孩是不是单身的？</a></p>
<p><a href="http://www.docin.com/p-297119165.html&amp;uid=34243720?bsh_bid=118134421">网络定向广告投放算法研究[专业：计算机应用技术]</a></p>
<p>&nbsp;</p>
<p>demo</p>
<p><a href="http://www.pudn.com/downloads171/sourcecode/windows/csharp/detail795644.html">http://www.pudn.com/downloads171/sourcecode/windows/csharp/detail795644.html</a></p>
<p><a href="http://www.newxing.com/Code/VC/suanfa/1287.html">http://www.newxing.com/Code/VC/suanfa/1287.html</a></p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=797</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>email提取工具 libextractemail</title>
		<link>https://www.softwareace.cn/?p=796</link>
		<comments>https://www.softwareace.cn/?p=796#comments</comments>
		<pubDate>Tue, 06 May 2014 09:26:54 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=796</guid>
		<description><![CDATA[&#160;]]></description>
				<content:encoded><![CDATA[<p><img alt="" src="http://static.oschina.net/uploads/img/201202/11085728_5DY2.png" /></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=796</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C/C++邮件发送包 libquickmail</title>
		<link>https://www.softwareace.cn/?p=795</link>
		<comments>https://www.softwareace.cn/?p=795#comments</comments>
		<pubDate>Tue, 06 May 2014 09:25:24 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=795</guid>
		<description><![CDATA[libquickmail 是一个 C/C++ 开发包，为开发者提供简单快速发送邮件的功能，支持多个 To/Cc [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>libquickmail 是一个 C/C++ 开发包，为开发者提供简单快速发送邮件的功能，支持多个 To/Cc/Bcc 接收者以及多 MIME 附加，没有大小限制。使用 libcurl 用于 SMTP 通讯。</p>
<p>http://sourceforge.net/p/libquickmail/</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=795</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>POP3、SMTP和IMAP</title>
		<link>https://www.softwareace.cn/?p=794</link>
		<comments>https://www.softwareace.cn/?p=794#comments</comments>
		<pubDate>Tue, 06 May 2014 09:24:16 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=794</guid>
		<description><![CDATA[POP3 POP3是Post Office Protocol 3的简称，即邮局协议的第3个版本,它规定怎样将个 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>POP3<br />
POP3是Post Office Protocol 3的简称，即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机（即自己的计算机）上,同时删除保存在邮件服务器上的邮件，而POP3服务器则是遵循POP3协议的接收邮件服务器，用来接收电子邮件的。(与IMAP有什么区别？)<br />
SMTP<br />
SMTP 的全称是“Simple Mail Transfer Protocol”，即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范，通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇，它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。<br />
SMTP 认证，简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器，这就使得那些垃圾邮件的散播者无可乘之机。<br />
增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。<br />
IMAP<br />
IMAP全称是Internet Mail Access Protocol，即交互式邮件存取协议，它是跟POP3类似邮件访问标准协议之一。不同的是，开启了IMAP后，您在电子邮件客户端收取的邮件仍然保留在服务器上，同时在客户端上的操作都会反馈到服务器上，如：删除邮件，标记已读等，服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱，看到的邮件以及状态都是一致的。（与POP3有什么区别？）</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=794</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>邮件群发</title>
		<link>https://www.softwareace.cn/?p=433</link>
		<comments>https://www.softwareace.cn/?p=433#comments</comments>
		<pubDate>Fri, 17 May 2013 06:56:47 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=433</guid>
		<description><![CDATA[[crayon-69f443dde9c0d702808552/] &#160; 关于生成随机QQ邮箱不精确的问 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">#include "stdafx.h"
#include &lt;windows.h&gt;
#include &lt;windowsx.h&gt;
#include "Resource.h"
#include "TabDlg1.h"
#include "winsock2.h"

#define MAXSTRING	10000
static int flag=0;                    //标记是否群发
TCHAR* pTitle = NULL;                 //指向标题文件内容的指针
HANDLE hThread=NULL;                  //线程返回句柄
long i=0;                             //列表控件“行”计数
static long sendNum=1;                //发送邮件数量

#pragma    comment(lib,"WSOCK32.LIB")

extern TCHAR tcRunPath[MAX_PATH];     //程序当前路径目录
extern TCHAR shortPath[MAX_PATH];     //文件路径，TAB2中的全局变量
extern TCHAR titlePath[256];          //邮件标题文件路径
extern TCHAR mtPath[256];             //邮件内容文件路径
extern TCHAR sendListPath[MAX_PATH];  //发送列表文件路径
extern BOOL attach;                   //是否添加了附件
extern TCHAR file[MAXSTRING];         //附件部份代码
BOOL WINAPI TAB1_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        HANDLE_MSG(hWnd, WM_INITDIALOG, TAB1_OnInitDialog);
        HANDLE_MSG(hWnd, WM_COMMAND, TAB1_OnCommand);
		HANDLE_MSG(hWnd,WM_CLOSE, TAB1_OnClose);
    }

    return FALSE;
}

BOOL TAB1_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
	InitLVColumn(hwnd);
	InitComboBox(hwnd);

    return TRUE;
}

void TAB1_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{	

	IsChecked(hwnd);         //判断勾选框是否被勾选
	IsRadioChecked(hwnd);    //RADIO控件是否被选择
    switch(id)
    {

        case IDC_MAIL_TEST:
		{		

			if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)!=BST_CHECKED &amp;&amp; IsDlgButtonChecked(hwnd,IDC_RADIO_163)!=BST_CHECKED)
			{
				MessageBox(hwnd,TEXT("请选择发QQ邮箱或163信箱"),"",MB_OK);
				return;
			}
			else
			{
				flag=0;
			    hThread=CreateThread(NULL,0,ThreadFunc,hwnd,0,0);

			}
		}
        break;
		case IDC_BUTTON_START:
		{		
			if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)!=BST_CHECKED &amp;&amp; IsDlgButtonChecked(hwnd,IDC_RADIO_163)!=BST_CHECKED)
			{
				MessageBox(hwnd,TEXT("请选择发QQ邮箱或163信箱"),"",MB_OK);
				return;
			}
			else
			{
				flag=1;
				hThread=CreateThread(NULL,0,ThreadFunc,hwnd,0,0);
		    }
		}
        break;
		case IDC_BUTTON_PAUSE:
		{			
			if(NULL!=hThread)
			{
			   SuspendThread(hThread);	
			}
			else
			{
				return;
			}
		}
        break;
		case IDC_BUTTON_RESUME:
		{			
			if(NULL!=hThread)
			{
			   ResumeThread(hThread);	
			}
			else
			{
				return;
			}
		}
        break;
        default:
		break;
    }
}

void TAB1_OnClose(HWND hwnd)
{
    EndDialog(hwnd, 0);
}

int InitLVColumn(HWND hwnd)              //列表初始化设置,视图选为报表视图
{
	LVCOLUMN lvColumn;
	MyLVColumn MyColumn[2] = {{TEXT("编号"), 0x30, LVCFMT_CENTER},{TEXT("邮箱帐号"), 0x99, LVCFMT_CENTER}};
	lvColumn.mask = LVCF_TEXT|LVCF_FMT|LVCF_WIDTH|LVCF_SUBITEM;
	DWORD dwStyle =ListView_GetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST));           //得到列表当前拓展风格
	dwStyle |= LVS_EX_FULLROWSELECT;    //选中某行使整行高亮（只适用与report风格的listctrl）
	dwStyle |= LVS_EX_GRIDLINES;        //网格线（只适用与report风格的listctrl）
//	dwStyle |= LVS_EX_CHECKBOXES;       //item前生成checkbox控件
	ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST),dwStyle);                  //设置列表扩展风格

	for(int i = 0; i &lt; 2; i++)
	{
		lvColumn.pszText = MyColumn[i].szColumnName;
		lvColumn.cx = MyColumn[i].cx;
		lvColumn.fmt = MyColumn[i].fmt;
		SendDlgItemMessage(hwnd, IDC_LIST, LVM_INSERTCOLUMN, i, (LPARAM)&amp;lvColumn);
	}

	return 0;
}

int InitComboBox(HWND hwnd)//窗口控件初始化设置
{
	HWND hwndCombo=GetDlgItem(hwnd,IDC_COMBO_SLEEPTIME);
	ComboBox_InsertString(hwndCombo,-1,TEXT("0"));
	ComboBox_InsertString(hwndCombo,-1,TEXT("1"));
	ComboBox_InsertString(hwndCombo,-1,TEXT("2"));
	ComboBox_InsertString(hwndCombo,-1,TEXT("5"));
	ComboBox_InsertString(hwndCombo,-1,TEXT("10"));
	ComboBox_InsertString(hwndCombo,-1,TEXT("20"));
	ComboBox_SetText(hwndCombo,TEXT("0"));

	SetDlgItemText(hwnd,IDC_EDIT_MAILADD,TEXT("12345678@qq.com"));
    ComboBox_InsertString(GetDlgItem(hwnd,IDC_COMBO_SMTP),0,TEXT("smtp.qq.com"));
    ComboBox_InsertString(GetDlgItem(hwnd,IDC_COMBO_SMTP),1,TEXT("smtp.163.com"));
	ComboBox_SetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),TEXT("smtp.qq.com"));
	SetDlgItemText(hwnd,IDC_EDIT_MAILPORT,TEXT("25"));	
	SetDlgItemText(hwnd,IDC_EDIT_USERNAME,TEXT(""));

	return 1;
}

int IsChecked(HWND hwnd)       //checkbox未选中的设置为只读
{
	if(IsDlgButtonChecked(hwnd,IDC_CHECK_QUNFA)!=BST_CHECKED)
	{
		EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_START), false);
		EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_RESUME), false);
		EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_PAUSE), false);
		return 0;
	}
	else
	{
		EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_START), true);
		EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_RESUME), true);
		EnableWindow(GetDlgItem(hwnd, IDC_BUTTON_PAUSE), true);
		return 1;
	}

	return 0;

}
int IsRadioChecked(HWND hwnd)    //RADIO控件被选中，则设置相应的SMTP 地址
{
	if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)==BST_CHECKED)
	{
	    ComboBox_SetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),TEXT("smtp.qq.com"));
		return 1;

	}
	if(IsDlgButtonChecked(hwnd,IDC_RADIO_163)==BST_CHECKED)
	{
	    ComboBox_SetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),TEXT("smtp.163.com"));
		return 2;
	}
	return 0;
}

TCHAR* readText1(HWND hwnd)             //读取文件--邮件发送内容
{
	int  nLen = 0;
	FILE *pF  = fopen(titlePath , "r"); //打开文件

	fseek(pF, 0, SEEK_END);             //文件指针移到文件尾
	nLen = ftell(pF);                   //得到当前指针位置, 即是文件的长度
	rewind(pF);                         //文件指针恢复到文件头位置

	pTitle = (char*) malloc(sizeof(char)*nLen+1);//动态申请空间, 为保存字符串结尾标志\0, 多申请一个字符的空间
	if(!pTitle)
	{
		MessageBox(hwnd,TEXT("内存不够!"),"错误",MB_ICONWARNING);
		exit(0);
	}
	nLen = fread(pTitle, sizeof(char), nLen, pF);

	pTitle[nLen] = '\0';          //添加字符串结尾标志

	if(IsDlgButtonChecked(hwnd,IDC_CHECK_TITLE)==BST_CHECKED)   //是否勾选在邮件标题 加入系统当前时间
	{
		SYSTEMTIME stLocal;
		GetLocalTime(&amp;stLocal);   //得到系统当前时间
		TCHAR strTime[256];
		ZeroMemory(strTime,sizeof(strTime)/sizeof(TCHAR));
		wsprintf(strTime,"%04u-%02u-%02u %02u:%02u:%02u",stLocal.wYear,stLocal.wMonth,stLocal.wDay,stLocal.wHour,stLocal.wMinute,stLocal.wSecond);
		strcat(pTitle,strTime);   //在标题后加入系统时间
	}
	fclose(pF);                   //关闭文件
	TCHAR* pText = NULL;
	pF  = fopen(mtPath , "r");    //打开文件
	fseek(pF, 0, SEEK_END); 
	nLen = ftell(pF);  
	rewind(pF);   

	pText = (char*) malloc(sizeof(char)*nLen+1); //动态申请空间, 为保存字符串结尾标志\0, 多申请一个字符的空间
	if(!pText)
	{
		MessageBox(hwnd,TEXT("内存不够!"),"错误",MB_ICONWARNING);
		exit(0);
	}
	nLen = fread(pText, sizeof(char), nLen, pF);

	pText[nLen] = '\0';          //添加字符串结尾标志

	fclose(pF);                  //关闭文件

	TCHAR chText[MAXSTRING];		
	TCHAR* encText=base64_encode(pText,strlen(pText));		
	strcpy(chText,encText);      //BASE64加密结果

	free(encText);               //释放指针
	free(pText);                 //释放空间

	return chText;
}

DWORD WINAPI ThreadFunc(LPVOID lpParam)//发邮件线程
{
	HWND hwnd=(HWND)lpParam;
	TCHAR userName[256];               //用户帐号
	TCHAR userPassWord[256];           //用户密码
	GetDlgItemText(hwnd,IDC_EDIT_USERNAME,userName,sizeof(userName)/sizeof(TCHAR));
	GetDlgItemText(hwnd,IDC_EDIT_USERPASSWORD,userPassWord,sizeof(userPassWord)/sizeof(TCHAR));

	TCHAR *name=userName; 
	int i = 0;    
	int j = strlen(name); 
	TCHAR *encName = base64_encode(name, j); 	            //给用户名base64加密编码		
	ZeroMemory(userName,sizeof(userName)/sizeof(TCHAR)); 
	wsprintf(userName,"%s\n", encName);                     //在加编码后加入回车符

	TCHAR *passWord=userPassWord; 
	int k = strlen(passWord); 
	TCHAR *encPassWord = base64_encode(passWord, k); 		//给用户密码base64加密编码				
	//	int len = strlen(enc);   
	//	TCHAR *dec = base64_decode(enc, len);	            //反编	
	ZeroMemory(userPassWord,sizeof(userPassWord)/sizeof(TCHAR)); 
	wsprintf(userPassWord,"%s\n", encPassWord);

	/*ZeroMemory(userName,sizeof(userName)/sizeof(TCHAR)); 
	wsprintf(userName,"\ndecoded : %s", dec);
	MessageBox(hwnd,userName,"",MB_OK);*/                   //反编译用户名，如果需要，可以把用户名密码反编后发到指定邮箱。

	free(encName);                                          //释放指针
	free(encPassWord);

	//free(dec); 
	if(1==flag)											    //全局标记，点击群发还是测试，1为群发，0为测试
	{
			HANDLE wFile;
			int szId;
			TCHAR ch;
			TCHAR szState[256];

			strcpy(sendListPath,tcRunPath);
		    strcat(sendListPath,"\\SendList.txt");          //拼接全路径及文件名
			TCHAR *sFileName=sendListPath;
			FILE *fp=fopen(sFileName,"r");

			if(fp==NULL)
		   {
				return FALSE;                              //打开文件失败，则返回，不读取
		   }

			fseek(fp, 0, SEEK_END);
			int length = ftell(fp);                        //length为0，则是空的
			rewind(fp);                                    //把指针移回文件头部 还可以用 fseek(fp, 0, SEEK_SET);效果一样
			if(length==0)                                  //判断文件如果为空，则关闭文件，返回，
			{
				fclose(fp);                                //要关闭打开的文件，不然退出时，无法保存
				return FALSE;
			}

			while(!feof(fp))
			{	

				fscanf(fp,"%s\r\n",szState);
				SocketQ(hwnd,userName,userPassWord,szState);

				TCHAR sTime[256];				
				unsigned long iTime;
				ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SLEEPTIME),sTime,sizeof(sTime)/sizeof(TCHAR));
				iTime=atoi(sTime);
				iTime=iTime*1000;
				Sleep(iTime);

			}	
			fclose(fp);

	}

	else
	{
		Socket(hwnd,userName,userPassWord);	
	}
	CloseHandle(hThread); 
	return 0;
}
void SocketQ(HWND hwnd,TCHAR userName[],TCHAR userPassWord[],TCHAR szState[])//传入加密的用户名跟密码连接163
{
		 /*******************************************************************
		 使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
		 该函数的第一个参数指明程序请求使用的Socket版本，
		 其中高位字节指明副版本、低位字节指明主版本；
		 操作系统利用第二个参数返回请求的Socket的版本信息。
		 当一个应用程序调用WSAStartup函数时，操作系统根据请求的Socket版本来搜索相应的Socket库，
		 然后绑定找到的Socket库到该应用程序中。
		 以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
		 该函数执行成功后返回0。
		 *****************************************************************/

		TCHAR* pText;
		pText = readText1(hwnd);

		int WSA_return;
		WSADATA wsaData;		 

	    WSA_return=WSAStartup(MAKEWORD(2,0),&amp;wsaData);       	//初始化Socket库		

		SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建SOCKET
		hostent*   host   =   NULL; 
		SOCKADDR_IN sa;

		sa.sin_family=AF_INET;		                            //设置电线连接服务器端的端口

		TCHAR cPort[100];
		GetDlgItemText(hwnd,IDC_EDIT_MAILPORT,cPort,sizeof(cPort)/sizeof(TCHAR));
		int iPort=atoi(cPort);
		sa.sin_port = htons(iPort);			
		//sa.sin_addr.S_un.S_addr = inet_addr("123.58.178.203");//可以写死IP地址			
		 HOSTENT *host_entry;                                   //存放主机域名，如smtp.qq.com

		 TCHAR host_name[256]="";
		 ZeroMemory(host_name,sizeof(host_name)/sizeof(TCHAR));	
		 ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),host_name,sizeof(host_name)/sizeof(TCHAR));

	     TCHAR str_ipAdd[256];
		 if(WSA_return==0)
		 {

		  host_entry=gethostbyname(host_name);                  // 要解析的域名或主机名 

		  if(host_entry!=NULL)
		  {

			wsprintf(str_ipAdd,"%d.%d.%d.%d",
				(host_entry-&gt;h_addr_list[0][0]&amp;0x00ff),
				(host_entry-&gt;h_addr_list[0][1]&amp;0x00ff),
				(host_entry-&gt;h_addr_list[0][2]&amp;0x00ff),
				(host_entry-&gt;h_addr_list[0][3]&amp;0x00ff));

		  }
		 }
		sa.sin_addr.S_un.S_addr = inet_addr(str_ipAdd);         //得到域名IP地址
		if(connect(sock,(SOCKADDR *)&amp;sa,sizeof(sa))==SOCKET_ERROR)

		{

		ShowError();
		return;

		}

		TCHAR buffer[256];                                     //对话过程		 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));

		int iRet=recv(sock,buffer,256,0);                      //接收问候语 		
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR Hello[] = "HELO SMTP\r\n";	                   //注意不能忘了末尾的回车 	 
		send(sock,Hello,lstrlen(Hello),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR Ehlo[] = "EHLO SMTP\r\n";		 
		send(sock,Ehlo,lstrlen(Ehlo),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR login[] = "AUTH LOGIN\r\n";		               //登陆命令
		send(sock,login,lstrlen(login),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)==BST_CHECKED)
		{
			strcat(userName,"\r\n");
			send(sock,userName,lstrlen(userName),0);           //发送加密的用户名
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

			strcat(userPassWord,"\r\n");
			send(sock,userPassWord,lstrlen(userPassWord),0);   //发送加密的密码
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}
		}
		if(IsDlgButtonChecked(hwnd,IDC_RADIO_163)==BST_CHECKED)
		{
			send(sock,userName,lstrlen(userName),0);           //发送加密的用户名
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));  
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

			send(sock,userPassWord,lstrlen(userPassWord),0);   //发送加密的密码
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}
		}

		TCHAR userF[256];
		TCHAR userL[256];
		TCHAR temp[256];

		GetDlgItemText(hwnd,IDC_EDIT_USERNAME,userF,sizeof(userF)/sizeof(TCHAR));	
	    ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),temp,sizeof(host_name)/sizeof(TCHAR));
		strcat(userF,"@");
        strncpy(userL,temp+5,sizeof(userL));
		strcat(userF,userL);
		TCHAR mailFrom[256];
		//MessageBox(hwnd,userF,"",MB_OK);
		wsprintf(mailFrom,TEXT("MAIL FROM:&lt;%s&gt;\r\n"),userF);
		send(sock,mailFrom,lstrlen(mailFrom),0);
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

			TCHAR mailTo[256];
 			wsprintf(mailTo,TEXT("RCPT TO:&lt;%s&gt;\r\n"),szState);
			send(sock,mailTo,lstrlen(mailTo),0);
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

		TCHAR dataCommad[]="DATA\r\n";
		send(sock,dataCommad,lstrlen(dataCommad),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		//下面是发送正文及附件部份
	    TCHAR data[50000];
	    TCHAR SetMailHead[1024];                      //邮件头部信息
		wsprintf(SetMailHead,TEXT("To:%s\r\nFrom:%s\r\nSubject: %s\r\n"
								   "Date:2012-8-24\r\nX-Mailer:Kevin's mailer\r\nMIME-Version:1.0\r\n"
								   "Content-Type: multipart/mixed;\r\n"
								   "	boundary=\"----=_NextPart_5039E410_D41071F0_120ABDFB\";\r\n"
								   "This is a multi-part message in MIME format.\r\n\r\n"
								   "------=_NextPart_5039E410_D41071F0_120ABDFB\r\n"
								   "Content-Type: multipart/alternative;\r\n"
								   "	boundary=\"----=_NextPart_5039E410_D41071F0_53510C95\";\r\n\r\n"
								   "------=_NextPart_5039E410_D41071F0_53510C95\r\n"
								   "Content-Type: text/plain;\r	charset=\"gb2312\"\r\n"
								   "Content-Transfer-Encoding: base64\r\n\r\n"),szState,userF,pTitle);

		strcat(SetMailHead,pText);                  //邮件头部再加上正文文本内容
		strcat(SetMailHead,TEXT("\r\n\r\n"));
		strcpy(data,SetMailHead);

		TCHAR SetMailHtml[1024];                    //邮件HTML代码部份
		wsprintf(SetMailHtml,TEXT("------=_NextPart_5039E410_D41071F0_53510C95\r\n"
								   "Content-Type: text/html;\r\n"
									"	charset=\"gb2312\"\r\n"
									"Content-Transfer-Encoding: base64\r\n\r\n"));

		strcat(SetMailHtml,pText);                  //加入邮件内容
		strcat(SetMailHtml,TEXT("\r\n\r\n------=_NextPart_5039E410_D41071F0_53510C95--\r\n\r\n"));

		strcat(data,SetMailHtml);

		if(TRUE==attach)                           //判断是否添加了附件路径
		{
		   strcat(data,file);                      //加入附件部份代码
		   strcat(data,TEXT("------=_NextPart_5039E410_D41071F0_120ABDFB--\r\n"));
		}

		send(sock,data,lstrlen(data),0);
		TCHAR cN[]="\r\n.\r\n";                    //邮件结束标志
		send(sock,cN,lstrlen(cN),0);

		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

		TCHAR cQuit[] = "QUIT\r\n";		            //退出命令
		send(sock,cQuit,lstrlen(cQuit),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);

		TCHAR cNum[256];
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}		 
		else
		{ 
			TCHAR str[256];                        //输出已发送列表
			wsprintf(str,"%i",sendNum);
			LVITEM lvItem;
			lvItem.mask = LVIF_TEXT;
			lvItem.iSubItem = 0;
			int ItemCount = ListView_GetItemCount(GetDlgItem(hwnd, IDC_LIST));
			lvItem.iItem = ItemCount;	

			lvItem.pszText = str;
			SendDlgItemMessage(hwnd, IDC_LIST, LVM_INSERTITEM, 0, (LPARAM)&amp;lvItem);	
			ListView_SetItemText(GetDlgItem(hwnd, IDC_LIST), i++, 1, szState);							
			sendNum++;

		}

;	
		free(pTitle);                              //释放空间		
		closesocket(sock);	                       //关闭SOCKET	 
		WSACleanup();
		return;
}

void Socket(HWND hwnd,TCHAR userName[],TCHAR userPassWord[])//传入加密的用户名跟密码连接163
{

		TCHAR* pText;
		pText = readText1(hwnd);

		int WSA_return;
		WSADATA wsaData;		 

	    WSA_return=WSAStartup(MAKEWORD(2,0),&amp;wsaData);//初始化Socket库		

		SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		hostent*   host   =   NULL; 
		SOCKADDR_IN sa;

		sa.sin_family=AF_INET;	                  	  //设置电线连接服务器端的端口

		TCHAR cPort[100];
		GetDlgItemText(hwnd,IDC_EDIT_MAILPORT,cPort,sizeof(cPort)/sizeof(TCHAR));
		int iPort=atoi(cPort);
		sa.sin_port = htons(iPort);		

		 HOSTENT *host_entry;

		 TCHAR host_name[256]="";
		 ZeroMemory(host_name,sizeof(host_name)/sizeof(TCHAR));	
		 ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),host_name,sizeof(host_name)/sizeof(TCHAR));

	     TCHAR str_ipAdd[256];
		 if(WSA_return==0)
		 {			 
		    host_entry=gethostbyname(host_name); // 即要解析的域名或主机名 

			 if(host_entry!=NULL)
			 {

				 wsprintf(str_ipAdd,"%d.%d.%d.%d",
				(host_entry-&gt;h_addr_list[0][0]&amp;0x00ff),
				(host_entry-&gt;h_addr_list[0][1]&amp;0x00ff),
				(host_entry-&gt;h_addr_list[0][2]&amp;0x00ff),
				(host_entry-&gt;h_addr_list[0][3]&amp;0x00ff));

			  }
		 }
		sa.sin_addr.S_un.S_addr = inet_addr(str_ipAdd);		 
		if(connect(sock,(SOCKADDR *)&amp;sa,sizeof(sa))==SOCKET_ERROR)
		{
			ShowError();
		   	return;	 
		}

		TCHAR buffer[256];                       //对话过程	 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR));		
		int iRet=recv(sock,buffer,256,0);        //接收问候语 
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR Hello[] = "HELO SMTP\r\n";		//注意不能忘了末尾的回车  
		send(sock,Hello,lstrlen(Hello),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR Ehlo[] = "EHLO SMTP\r\n";		 
		send(sock,Ehlo,lstrlen(Ehlo),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR login[] = "AUTH LOGIN\r\n";		              //登陆命令
		send(sock,login,lstrlen(login),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		if(IsDlgButtonChecked(hwnd,IDC_RADIO_QQ)==BST_CHECKED)
		{
			strcat(userName,"\r\n");
			send(sock,userName,lstrlen(userName),0);         //发送加密的用户名
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

			strcat(userPassWord,"\r\n");
			send(sock,userPassWord,lstrlen(userPassWord),0); //发送加密的密码
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}
		}
		if(IsDlgButtonChecked(hwnd,IDC_RADIO_163)==BST_CHECKED)
		{
			send(sock,userName,lstrlen(userName),0);         //发送加密的用户名
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

			send(sock,userPassWord,lstrlen(userPassWord),0); //发送加密的密码
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}
		}

		TCHAR userF[256];
		TCHAR userL[256];
		TCHAR temp[256];
		GetDlgItemText(hwnd,IDC_EDIT_USERNAME,userF,sizeof(userF)/sizeof(TCHAR));	
		ComboBox_GetText(GetDlgItem(hwnd,IDC_COMBO_SMTP),temp,sizeof(host_name)/sizeof(TCHAR));
		strcat(userF,"@");
        strncpy(userL,temp+5,sizeof(userL));
		strcat(userF,userL);
		TCHAR mailFrom[256];
		//MessageBox(hwnd,userF,"",MB_OK);
		wsprintf(mailFrom,TEXT("MAIL FROM:&lt;%s&gt;\r\n"),userF);
		send(sock,mailFrom,lstrlen(mailFrom),0);
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

			TCHAR mailAdd[256];
			GetDlgItemText(hwnd,IDC_EDIT_MAILADD,mailAdd,sizeof(mailAdd)/sizeof(TCHAR));
			TCHAR mailTo[256];
 			wsprintf(mailTo,TEXT("RCPT TO:&lt;%s&gt;\r\n"),mailAdd);
			send(sock,mailTo,lstrlen(mailTo),0);
			ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
			iRet=recv(sock,buffer,256,0);
			if(SOCKET_ERROR==iRet)
			{
				ShowError();		 
				return;
			}

		TCHAR dataCommad[]="DATA\r\n";
		send(sock,dataCommad,lstrlen(dataCommad),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		//下面是发送正文及附件部份
	    TCHAR data[50000];
	    TCHAR SetMailHead[1024];                       //邮件头部信息
		wsprintf(SetMailHead,TEXT("To:%s\r\nFrom:%s\r\nSubject: %s\r\n"
								   "Date:2012-8-24\r\nX-Mailer:Kevin's mailer\r\nMIME-Version:1.0\r\n"
								   "Content-Type: multipart/mixed;\r\n"
								   "	boundary=\"----=_NextPart_5039E410_D41071F0_120ABDFB\";\r\n"
								   "This is a multi-part message in MIME format.\r\n\r\n"
								   "------=_NextPart_5039E410_D41071F0_120ABDFB\r\n"
								   "Content-Type: multipart/alternative;\r\n"
								   "	boundary=\"----=_NextPart_5039E410_D41071F0_53510C95\";\r\n\r\n"
								   "------=_NextPart_5039E410_D41071F0_53510C95\r\n"
								   "Content-Type: text/plain;\r	charset=\"gb2312\"\r\n"
								   "Content-Transfer-Encoding: base64\r\n\r\n"),mailAdd,userF,pTitle);

		strcat(SetMailHead,pText);                     //邮件头部再加上正文文本内容

		strcat(SetMailHead,TEXT("\r\n\r\n"));
		strcpy(data,SetMailHead);

		TCHAR SetMailHtml[1024];                       //邮件HTML代码部份
		wsprintf(SetMailHtml,TEXT("------=_NextPart_5039E410_D41071F0_53510C95\r\n"
								   "Content-Type: text/html;\r\n"
									"	charset=\"gb2312\"\r\n"
									"Content-Transfer-Encoding: base64\r\n\r\n"));
		strcat(SetMailHtml,pText);                     //加入邮件内容
		strcat(SetMailHtml,TEXT("\r\n\r\n------=_NextPart_5039E410_D41071F0_53510C95--\r\n\r\n"));

		strcat(data,SetMailHtml);

		if(TRUE==attach)                               //判断是否添加了附件路径
		{
		   strcat(data,file);                          //加入附件部份代码
		   strcat(data,TEXT("------=_NextPart_5039E410_D41071F0_120ABDFB--\r\n"));
		}

		send(sock,data,lstrlen(data),0);

		TCHAR cN[]="\r\n.\r\n";                        //邮件结束标志
		send(sock,cN,lstrlen(cN),0);
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}

		TCHAR cQuit[] = "QUIT\r\n";		                //退出命令
		send(sock,cQuit,lstrlen(cQuit),0); 
		ZeroMemory(buffer,sizeof(buffer)/sizeof(TCHAR)); 
		iRet=recv(sock,buffer,256,0);

		TCHAR cNum[256];
		if(SOCKET_ERROR==iRet)
		{
			ShowError();		 
			return;
		}		 
		else
		{ 	  
		   MessageBox(hwnd,TEXT("测试发送成功"),TEXT("恭喜"),MB_OK);
		}

		 free(pTitle);                                 //释放空间
		closesocket(sock);                             //关闭SOCK		 
		WSACleanup();
		return;
}

void ShowError()

{

	TCHAR* lpMsgBuf;

	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|     //自动分配消息缓冲区

	FORMAT_MESSAGE_FROM_SYSTEM,                       //从系统获取信息

	NULL,GetLastError(),                              //获取错误信息标识

	MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),         //使用系统缺省语言

	(LPTSTR)&amp;lpMsgBuf,                                //消息缓冲区

	0,

	NULL);

	MessageBox(NULL,lpMsgBuf,"",MB_ICONERROR); 
}</pre><p>&nbsp;</p>
<p>关于生成随机QQ邮箱不精确的问题，在之后版本打算另写一个采集器插件进行帐号采集，所以，这个软件只用来进行内容发送，邮箱进行随机生成<br />
如果你已经有采集来的QQ号，请复制到SendList.txt 替换内容即可<br />
可以直接复制HTML代码到邮件内容，保存即可。目前邮件内容最大设置为10000字节，如果有增大的必要，欢迎提交留言。<br />
源码出处，可以直接打包下载工程</p>
<p>这是我学习后VC编程中涉及到多线程,socket,及一些WINDOWS API的宗合应用</p>
<p>使用说明：</p>
<p>一、SMTP设置</p>
<p>1、SMTP设置中，收件箱地址：填写邮箱地址为帐号测试邮箱，可以填写你自己的邮箱作为接收测试。打星号为必填。邮箱帐号及密码，是即将用于群发的帐号和密码</p>
<p>2、群发发送时间间隔，默认为零，可以选择填写发送间隔时间，单位为秒，防止多次快速发送相同内容被停用。</p>
<p>3、勾选邮件标题后插入系统时间，可以在标题上加上系统时间</p>
<p>4、导入群发列表，勾选后，可以点击群发，暂停，继续。（群发列表为程序目录中SendList.txt)如果你有邮箱采集软件，可以把彩集的邮箱地址按照格式，一行一个，放入其中），没有的话，可以点击“收件箱”页面生成随机QQ邮箱</p>
<p>二、邮件内容</p>
<p>1、填写邮件标题，邮件内容可以为纯文本，也可以是HTML代码，附件目前只支持TXT文本。</p>
<p>2、群发前，请测试邮件内容，是否完整。附件是否正常接收。</p>
<p>三、收件箱</p>
<p>1、收件箱中顺序生成QQ邮箱，请不要超过6位数QQ号，位数过大，生成时间过长，容易造成假死。</p>
<p>2、群发前，先生成QQ邮箱列表。如果你有采集邮箱帐号，可以按格式放入SendList.txt 中</p>
<p>版本更新说明：<br />
3.1版本 2012-8-28</p>
<p>1、可增加多个附件。<br />
2、修复标题插入日期造成程序崩溃的BUG。<br />
3、增加发送间隔时间选项。<br />
4、支持HTML代码<br />
5、增加干预码</p>
<div>
<p><strong>源码与演示：</strong><a onclick="javascript:void(0);" href="http://returnc.com/wp-content/uploads/2012/12/QQ-Smtp-sever1.0.rar" target="_blank">源码出处</a> <a onclick="javascript:void(0);" href="http://returnc.com/archives/300.html" target="_blank">演示出处</a></p>
<p>&nbsp;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=433</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
