<?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>Here comes the Sun &#187; captcha</title>
	<atom:link href="http://sunng.info/blog/tag/captcha/feed/" rel="self" type="application/rss+xml" />
	<link>http://sunng.info/blog</link>
	<description>Homemade Clojure Geek</description>
	<lastBuildDate>Fri, 11 May 2012 02:24:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>New composite based captcha image</title>
		<link>http://sunng.info/blog/2010/01/new-composite-based-captcha-image/</link>
		<comments>http://sunng.info/blog/2010/01/new-composite-based-captcha-image/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 14:54:39 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=429</guid>
		<description><![CDATA[recaptcha的验证码新增了alpha composite的新机制取代干扰线，今天用了一些时间在YAN上也实现了这种绘图机制。 使用Java2D的AlphaComposite实现，选用的Rule为alpha 1.0的SrcOut，即通过公式 Ar = As * (1 – Ad ) Cr = Cs * (1 – Ad ) 用语言描述就是叠加区域的透明度为0. 使用这种机制必须采用BufferedImage.TYPE_INT_ARGB的图像，并且输出支持alpha通道的格式。]]></description>
			<content:encoded><![CDATA[<p>recaptcha的验证码新增了alpha composite的新机制取代干扰线，今天用了一些时间在<a href="http://bitbucket.org/sunng/yan/" target="_blank">YAN</a>上也实现了这种绘图机制。</p>
<p><a title="30a2512d899641a8ab79a7c86946ff71 by 贝小塔, on Flickr" href="http://www.flickr.com/photos/40741608@N08/4308533479/"><img src="http://farm3.static.flickr.com/2752/4308533479_42337f4525_o.png" alt="30a2512d899641a8ab79a7c86946ff71" width="300" height="100" /></a><br />
<a title="f03ec596b91b4ce985c5b5af4a79e961 by 贝小塔, on Flickr" href="http://www.flickr.com/photos/40741608@N08/4308533483/"><img src="http://farm5.static.flickr.com/4068/4308533483_a9e687b74c_o.png" alt="f03ec596b91b4ce985c5b5af4a79e961" width="300" height="100" /></a></p>
<p>使用Java2D的AlphaComposite实现，选用的Rule为alpha 1.0的SrcOut，即通过公式</p>
<p>Ar = As * (1 – Ad )<br />
Cr = Cs * (1 – Ad )<br />
用语言描述就是叠加区域的透明度为0. 使用这种机制必须采用BufferedImage.TYPE_INT_ARGB的图像，并且输出支持alpha通道的格式。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2010/01/new-composite-based-captcha-image/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hush!</title>
		<link>http://sunng.info/blog/2009/12/hush/</link>
		<comments>http://sunng.info/blog/2009/12/hush/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 11:57:34 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[留影]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=400</guid>
		<description><![CDATA[今天新增的拼图验证码的可配置性非常强，你只要替换资源文件，在配置文件中修改提问的模版，指定图片的大小、行数、列数，就可以创造一套全新的验证码。他的简单程度实在超出你的想象。]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" src="http://farm3.static.flickr.com/2577/4215800886_9e33ac4830_o.png" alt="" width="329" height="492" /></p>
<p>今天新增的拼图验证码的可配置性非常强，你只要替换资源文件，在配置文件中修改提问的模版，指定图片的大小、行数、列数，就可以创造一套全新的验证码。他的简单程度实在超出你的想象。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/12/hush/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Web 2.0 Icon Captcha</title>
		<link>http://sunng.info/blog/2009/12/web-2-0-icon-captcha/</link>
		<comments>http://sunng.info/blog/2009/12/web-2-0-icon-captcha/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 07:29:39 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=393</guid>
		<description><![CDATA[Yan 新增了一种验证码类型，Web 2.0 图标验证码。用户根据图标的内容和提示的信息，提交验证码。验证码图片如下： 提示文字： Please figure out twitter icons. 用户输入Twitter图标左上角上的字母，即可进行验证。在Yan的测试界面上使用如图： Web2.0 Icon实际上是Yan中新增的拼图验证码的一个实例，利用拼图验证码可以生成相似的更有创意的验证码。在我的开发环境中生成这样一张图片大约需要80ms。 项目中使用的图标均从互联网收集，遵循CC等协议或经作者授权，详情参考项目中README文件。 祝DAF同学生日快乐。]]></description>
			<content:encoded><![CDATA[<p>Yan 新增了一种验证码类型，Web 2.0 图标验证码。用户根据图标的内容和提示的信息，提交验证码。验证码图片如下：</p>
<p><img class="alignnone" src="http://farm3.static.flickr.com/2556/4215434144_f589085acd_o.png" alt="" width="256" height="192" /></p>
<p>提示文字： Please figure out twitter icons.</p>
<p>用户输入Twitter图标左上角上的字母，即可进行验证。在Yan的测试界面上使用如图：</p>
<p><img class="alignnone" src="http://farm3.static.flickr.com/2565/4214663971_cdc2168f69_o.png" alt="" width="394" height="503" /></p>
<p>Web2.0 Icon实际上是Yan中新增的拼图验证码的一个实例，利用拼图验证码可以生成相似的更有创意的验证码。在我的开发环境中生成这样一张图片大约需要80ms。</p>
<p>项目中使用的图标均从互联网收集，遵循CC等协议或经作者授权，详情参考项目中README文件。</p>
<p>祝DAF同学生日快乐。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/12/web-2-0-icon-captcha/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Load Test on Yan</title>
		<link>http://sunng.info/blog/2009/12/load-test-on-yan/</link>
		<comments>http://sunng.info/blog/2009/12/load-test-on-yan/#comments</comments>
		<pubDate>Fri, 25 Dec 2009 04:07:19 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=382</guid>
		<description><![CDATA[给Yan的验证码图片服务做了压力测试。测试环境： Intel Xeon 3.00GHz 4核 内存2G Red Hat Enterprise Linux AS release 4 (Nahant Update 7) Jetty 6 / JDK 6 Jetty采用默认配置 maxThreads 200。 测试工具：ab (Apache Bench) 分别用10/50/100/200/500/1000并发用户，每个用户请求100次进行测试。结果如下： 10 50 100 200 500 1000 Requests per second 487.11 472.09 442.74 &#8230; <a href="http://sunng.info/blog/2009/12/load-test-on-yan/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>给Yan的验证码图片服务做了压力测试。测试环境：</p>
<ul>
<li>Intel Xeon 3.00GHz 4核</li>
<li>内存2G</li>
<li>Red Hat Enterprise Linux AS release 4 (Nahant Update 7)</li>
<li>Jetty 6 / JDK 6</li>
</ul>
<p>Jetty采用默认配置 maxThreads 200。</p>
<p>测试工具：ab (Apache Bench)</p>
<p>分别用10/50/100/200/500/1000并发用户，每个用户请求100次进行测试。结果如下：</p>
<p><!--   		BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"宋体"; font-size:x-small } --></p>
<p><!--   		BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"宋体"; font-size:x-small } --></p>
<table border="0" cellspacing="0" frame="VOID" rules="NONE">
<colgroup>
<col width="161"></col>
<col width="159"></col>
<col width="167"></col>
<col width="169"></col>
<col width="160"></col>
<col width="145"></col>
<col width="136"></col>
</colgroup>
<tbody>
<tr>
<td align="LEFT"></td>
<td align="RIGHT"><span style="font-family: Arial;">10</span></td>
<td align="RIGHT"><span style="font-family: Arial;">50</span></td>
<td align="RIGHT"><span style="font-family: Arial;">100</span></td>
<td align="RIGHT"><span style="font-family: Arial;">200</span></td>
<td align="RIGHT"><span style="font-family: Arial;">500</span></td>
<td align="RIGHT"><span style="font-family: Arial;">1000</span></td>
</tr>
<tr>
<td align="LEFT"><span style="font-family: Arial;">Requests per second</span></td>
<td align="RIGHT"><span style="font-family: Arial;">487.11</span></td>
<td align="RIGHT"><span style="font-family: Arial;">472.09</span></td>
<td align="RIGHT"><span style="font-family: Arial;">442.74</span></td>
<td align="RIGHT"><span style="font-family: Arial;">421.63</span></td>
<td align="RIGHT"><span style="font-family: Arial;">408.11</span></td>
<td align="RIGHT"><span style="font-family: Arial;">326.12</span></td>
</tr>
<tr>
<td align="LEFT"><span style="font-family: Arial;">Time per request</span></td>
<td align="RIGHT"><span style="font-family: Arial;">2.05</span></td>
<td align="RIGHT"><span style="font-family: Arial;">2.12</span></td>
<td align="RIGHT"><span style="font-family: Arial;">2.26</span></td>
<td align="RIGHT"><span style="font-family: Arial;">2.37</span></td>
<td align="RIGHT"><span style="font-family: Arial;">2.45</span></td>
<td align="RIGHT"><span style="font-family: Arial;">3.07</span></td>
</tr>
<tr>
<td align="LEFT"><span style="font-family: Arial;">Transfer rate</span></td>
<td align="RIGHT"><span style="font-family: Arial;">987.91</span></td>
<td align="RIGHT"><span style="font-family: Arial;">955.54</span></td>
<td align="RIGHT"><span style="font-family: Arial;">896.85</span></td>
<td align="RIGHT"><span style="font-family: Arial;">854.31</span></td>
<td align="RIGHT"><span style="font-family: Arial;">826.25</span></td>
<td align="RIGHT"><span style="font-family: Arial;">660.45</span></td>
</tr>
</tbody>
</table>
<p>﻿<img class="alignnone" src="http://farm3.static.flickr.com/2677/4212622846_f6023f9b40_o.png" alt="" width="358" height="334" /></p>
<p>目前对每个请求独立使用JDK的awt实时绘图，吞吐量可以达到400以上，如果稍稍优化一下Jetty的配置，性能还有一定的提升空间。这个结果还是不错的。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/12/load-test-on-yan/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Yan in Ruby Web Application</title>
		<link>http://sunng.info/blog/2009/12/use-yan-in-ruby-web-application/</link>
		<comments>http://sunng.info/blog/2009/12/use-yan-in-ruby-web-application/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 15:16:45 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[把戏]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=360</guid>
		<description><![CDATA[I will show you the usage of Yan captcha service. In this tutorial, it&#8217;s based on a simple ruby web application of the Sinatra web framework. Before we start to use the service, it is necesary to get Yan running. &#8230; <a href="http://sunng.info/blog/2009/12/use-yan-in-ruby-web-application/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I will show you the usage of Yan captcha service. In this tutorial, it&#8217;s based on a simple ruby web application of the Sinatra web framework.</p>
<p>Before we start to use the service, it is necesary to get Yan running. Download the code from <a href="http://bitbucket.org/sunng/yan/" target="_blank">the project page</a>, then build and run it with maven:<br />
<em>mvn jetty:run</em></p>
<p>To enable the application to use Yan, we have to register our application to get an API Key. If you use Yan 0.3, there is a secret registration page at <em>http://localhost:8080/yan/reg.jsp</em> The page is protected by HTTP Basic Authentication, the username and password are store in &#8216;realm.properties&#8217; which is considered to locate in the root directory. Open the file you can see the plain text username and password. If you are running the latest development version, there is no long any UI for API Key creation, but restful interface. This won&#8217;t be hard to you, pickup your tools such as curl or poster (a firefox extension) to send a HTTP request. Take curl as example, do it like this:<br />
<em>curl -X PUT &#8220;http://localhost:8080/yan/apikey/&#8221; -d &#8220;SinatraTestApp&#8221; -u &#8220;username:password&#8221;</em></p>
<p>If it works, you will get a line of json:<br />
<em>{&#8220;apikey&#8221;:&#8221;b251b0dc2eed31cac38555b61d4fa6a453923bfd&#8221;,&#8221;appName&#8221;:&#8221;SinatraTestApp&#8221;}</em><br />
Save this apikey.</p>
<p>Sinatra is generally considered to be the world&#8217;s lightest and smallest web framework. And our application is rather simple. Just check the code:</p>
<pre class="brush:ruby">require "rubygems"
require "sinatra"
require "net/http"
require "yaml"

apikey='b251b0dc2eed31cac38555b61d4fa6a453923bfd'

get '/' do
	conn = Net::HTTP.new('localhost', 8080)
	q = "ip=#{@env['REMOTE_ADDR']}&amp;apikey=#{apikey}&amp;alt=yaml&amp;mode=0"
	resp, data = conn.get("/yan/ticket?#{q}")
	@ticket = YAML::load(data)
	haml :sinatra_captcha
end

post '/' do
	conn = Net::HTTP.new('localhost', 8080)
	q = "ip=#{@env['REMOTE_ADDR']}&amp;apikey=#{apikey}&amp;key=#{params['key']}&amp;code=#{params['captcha']}"
	resp, data = conn.get("/yan/validate?#{q}")
	data
end

use_in_file_templates!
__END__

@@ sinatra_captcha
%html
	%head
		%title Yan Captcha on Sinatra
	%body
		%form{:action=&gt;"/", :method=&gt;"post"}
			%p
				Username:
				%input{:name=&gt;"username", :type=&gt;"text"}
			%p
				Password:
				%input{:name=&gt;"password", :type=&gt;"password"}
			%p
				Captcha:
				%img{:src=&gt;@ticket['url']}
				%br
				%input{:name=&gt;"captcha", :type=&gt;"text"}
				%input{:name=&gt;"key", :type=&gt;"hidden", :value=&gt;@ticket['key']}
				%input{:type=&gt;'submit'}
</pre>
<p>There are two parts of this application: ruby code and haml. I just use in-file-template for convenience. We define a get handler and a post handler on the path &#8216;/&#8217;. The get handler will request a ticket from Yan which contains captcha image url and ticket key. The post handler will extract user input and submit the Yan&#8217;s validator and return user the result. And the HAML code is template for page rendering after GET request.</p>
<p>Maybe you need to install sinatra and some dependency:<br />
<em>sudo gem install sinatra haml</em></p>
<p>Run the code with a build-in WEBrick<br />
<em>ruby sinatra-yan.rb</em></p>
<p>Browse to the default url, test it:</p>
<p><img class="alignnone" src="http://farm3.static.flickr.com/2766/4203612734_3237ed066c_o.png" alt="" width="459" height="268" /></p>
<p>For another similar tutorial using python, check Yan&#8217;s wiki page:<br />
<a href="http://bitbucket.org/sunng/yan/wiki/SampleCode" target="_blank">http://bitbucket.org/sunng/yan/wiki/SampleCode</a></p>
<p>Thank you for your support. btw, today is my dear girl friend&#8217;s birthday, I just wish her happy everyday.</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/12/use-yan-in-ruby-web-application/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Yan 0.3</title>
		<link>http://sunng.info/blog/2009/12/yan-0-3/</link>
		<comments>http://sunng.info/blog/2009/12/yan-0-3/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 14:51:10 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=357</guid>
		<description><![CDATA[经过一周的重构和开发，我的开源项目，验证码服务，打上了0.3的tag，算是一个release吧。 This release has been focusing on support for different types captcha generators. Now Yan is not only able to provide image/jpeg captcha, but also text/plain and any others. Changeset: Internal API Changes: Cache API improved: new CacheItemIdentity and CacheIdStrategy &#8230; <a href="http://sunng.info/blog/2009/12/yan-0-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>经过一周的重构和开发，我的开源项目，验证码服务，打上了0.3的tag，算是一个release吧。</p>
<p>This release has been focusing on support for different types captcha generators. Now Yan is not only able to provide image/jpeg captcha, but also text/plain and any others.</p>
<h3>Changeset:</h3>
<ul>
<li>Internal API Changes:
<ul>
<li>Cache API improved: new CacheItemIdentity and CacheIdStrategy were introduced in to provide convertion between cache item name and captcha info model;</li>
<li>Captcha Generator API improved: Add CaptchaGeneratorInfo to define some meta information on captcha providers (such as mode code, captcha type);</li>
<li>Captcha Data Model(CaptchaInfo) and Ticket Data Model improved: configuration parameters are separated from required parameters and has been more generic for different types of generator algorisms;</li>
</ul>
</li>
<li>External API Changes:
<ul>
<li>Rename /image url to /captcha for better literal accuracy;</li>
<li>/ticket now supports multiple types of applicable format (plain text / json / xml / yaml);</li>
<li>/ticket now returns the mime type of the captcha generator;</li>
<li>Add a Simple-Plain-Text generator as a sample for those whose mime type is other than image/jpeg;</li>
</ul>
</li>
<li>Other changes:
<ul>
<li>I created a new branch for next version of Yan. So the code in repository now has multiply branches, you can use &#8216;hg update branch-name&#8217; to switch between difference branches;</li>
<li>The sample test page for the service (index.jsp) has been adopt to the new protocol and totally restyled.</li>
</ul>
</li>
</ul>
<p><img class="alignnone" src="http://farm3.static.flickr.com/2503/4200328968_b3dd1fee5f.jpg" alt="" width="500" height="391" /></p>
<p>Again, grab code from the development repository:<br />
<em>hg clone https://sunng@bitbucket.org/sunng/yan/</em></p>
<p>If you don&#8217;t use mercurial/hg, you can also download the tagged version from the page:<br />
<a href="http://bitbucket.org/sunng/yan/downloads/" target="_blank"><em>http://bitbucket.org/sunng/yan/downloads/</em></a></p>
<p>Just use maven to resolve dependency, build and run the project:<br />
<em>mvn jetty:run</em></p>
<p>Feel free to report issue <img src='http://sunng.info/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/12/yan-0-3/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Yan Captcha Service</title>
		<link>http://sunng.info/blog/2009/10/yan-captcha-service/</link>
		<comments>http://sunng.info/blog/2009/10/yan-captcha-service/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 15:32:58 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[把戏]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[Yan]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=291</guid>
		<description><![CDATA[I&#8217;d like to announce my recent works, a project called Yan Captcha Service written in Java which is aimed to provide whole solutions of captcha for your websites. It will be very easy to use the service because 1. interfaces &#8230; <a href="http://sunng.info/blog/2009/10/yan-captcha-service/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d like to announce my recent works, a project called Yan Captcha Service written in Java which is aimed to provide whole solutions of captcha for your websites. It will be very easy to use the service because 1. interfaces are based on plain http url; 2. different kinds of usage are supported to fit your requirements; 3. the architecture is open so you can add your own solid implementation of captcha; 4. less coupling with your system. And designed for scalability, currently, it applies JGroups to share sessions (memcached support will be added soon), thus you can setup a cluster for the service.</p>
<p>As you may know, the open-source project is split from my current work-time project because it is more closed to my idea. However, soon we will have the product opened to our thousands (millions ?) of users. I can gain feedback from the challenge and improve the open-source edition.</p>
<p>The code is maintained by open-source scm, mercurial (also known as hg). The project is now hosted on <a href="http://bitbucket.org/sunng/yan/">bitbucket.org</a>. You can clone the code to local via:<br />
<em>$ hg clone https://sunng@bitbucket.org/sunng/yan/</em></p>
<p>To build the project, run this command in root of project directory:<br />
<em>mvn install</em></p>
<p>To run in a develop environment:<br />
<em>mvn jetty:run</em></p>
<p><a href="http://bitbucket.org/sunng/yan/issues/?status=new&amp;status=open" target="_blank">Issue reporting</a> and patches are always welcomed.</p>
<p>Check the wiki pages for more information about the project:<br />
<a href="http://bitbucket.org/sunng/yan/wiki/Home">http://bitbucket.org/sunng/yan/wiki/Home</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/10/yan-captcha-service/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>另一种验证码方式</title>
		<link>http://sunng.info/blog/2009/10/%e5%8f%a6%e4%b8%80%e7%a7%8d%e9%aa%8c%e8%af%81%e7%a0%81%e6%96%b9%e5%bc%8f/</link>
		<comments>http://sunng.info/blog/2009/10/%e5%8f%a6%e4%b8%80%e7%a7%8d%e9%aa%8c%e8%af%81%e7%a0%81%e6%96%b9%e5%bc%8f/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 12:27:37 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[手艺]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=273</guid>
		<description><![CDATA[今天又讨论了一种验证码服务的机制，这种机制相对前两天说的简化的验证码生成的部分，由两步生成变成了一步生成，当然由于生成图片的接口直接暴露给用户，存在被刷的可能。 用户浏览器向应用服务器请求包含验证码的页面； 应用服务器将包含验证码地址的网页发送给用户浏览器； 用户浏览器通过img的src中的固定链接向验证码服务器请求验证码图片； 验证码服务器输出验证码图片流到用户浏览器，将sessionid写入cookie； 用户判读验证码图片，提交表单； 应用服务器取出cookie中的sessionid和用户输入发往验证码服务器； 验证码服务器进行验证，返回通过或拒绝； 应用服务器根据验证码服务器结果进行响应。 优点： 固定链接，简化了接入，便于接入静态页面； 缺点： 写cookie受到域的限制，只能在相同的域中使用该服务； 验证码接口暴露给用户，可能被穷举 百度和腾讯使用的都是这种方式。]]></description>
			<content:encoded><![CDATA[<p>今天又讨论了一种验证码服务的机制，这种机制相对前两天说的简化的验证码生成的部分，由两步生成变成了一步生成，当然由于生成图片的接口直接暴露给用户，存在被刷的可能。</p>
<p><img class="alignnone" src="http://farm4.static.flickr.com/3499/4013396855_6c5a02b7c7.jpg" alt="" width="500" height="310" /></p>
<ol>
<li>用户浏览器向应用服务器请求包含验证码的页面；</li>
<li>应用服务器将包含验证码地址的网页发送给用户浏览器；</li>
<li>用户浏览器通过img的src中的固定链接向验证码服务器请求验证码图片；</li>
<li>验证码服务器输出验证码图片流到用户浏览器，将sessionid写入cookie；</li>
<li>用户判读验证码图片，提交表单；</li>
<li>应用服务器取出cookie中的sessionid和用户输入发往验证码服务器；</li>
<li>验证码服务器进行验证，返回通过或拒绝；</li>
<li>应用服务器根据验证码服务器结果进行响应。</li>
</ol>
<p>优点：<br />
固定链接，简化了接入，便于接入静态页面；</p>
<p>缺点：<br />
写cookie受到域的限制，只能在相同的域中使用该服务；<br />
验证码接口暴露给用户，可能被穷举</p>
<p>百度和腾讯使用的都是这种方式。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/10/%e5%8f%a6%e4%b8%80%e7%a7%8d%e9%aa%8c%e8%af%81%e7%a0%81%e6%96%b9%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>验证码服务recaptcha和vidoop</title>
		<link>http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e6%9c%8d%e5%8a%a1recaptcha%e5%92%8cvidoop/</link>
		<comments>http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e6%9c%8d%e5%8a%a1recaptcha%e5%92%8cvidoop/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 09:12:27 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[手艺]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=265</guid>
		<description><![CDATA[某人已经发展到上班时间写blog了。 继续说验证码服务，找到两个比较典型的。recaptcha非常著名，是twitter和facebook使用的验证码服务（不知道现在的情况。。。），vidoop提供了一种很有特点的验证码机制。 两个服务都提供了python的接口封装便于接入，通过api接口可以管中窥豹，大致了解这两个验证服务的机制。 recaptcha 下面是一段结合了web.py的简单调用 public_key = "******" private_key = "********" class Recaptcha(object): def GET(self): r = recaptcha.displayhtml(public_key) return render.recapt(r) def POST(self): params = web.input() recaptcha_challenge_field, recaptcha_response_field = params.recaptcha_challenge_field, params.recaptcha_response_field remote_ip = web.ctx.ip result = recaptcha.submit(recaptcha_challenge_field, recaptcha_response_field, private_key, remote_ip) return &#8230; <a href="http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e6%9c%8d%e5%8a%a1recaptcha%e5%92%8cvidoop/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>某人已经发展到上班时间写blog了。</p>
<p>继续说验证码服务，找到两个比较典型的。<a href="http://recaptcha.net/" target="_blank">recaptcha</a>非常著名，是twitter和facebook使用的验证码服务（不知道现在的情况。。。），<a href="http://vidoop.com/" target="_blank">vidoop</a>提供了一种很有特点的验证码机制。</p>
<p>两个服务都提供了python的接口封装便于接入，通过api接口可以管中窥豹，大致了解这两个验证服务的机制。</p>
<h3>recaptcha</h3>
<p>下面是一段结合了web.py的简单调用</p>
<pre class="brush:python">public_key = "******"
private_key = "********"
class Recaptcha(object):
    def GET(self):
        r = recaptcha.displayhtml(public_key)
        return render.recapt(r)

    def POST(self):
        params = web.input()
        recaptcha_challenge_field, recaptcha_response_field = params.recaptcha_challenge_field, params.recaptcha_response_field
        remote_ip = web.ctx.ip
        result = recaptcha.submit(recaptcha_challenge_field, recaptcha_response_field, private_key, remote_ip)
        return result.is_valid</pre>
<p>我在GET请求中获取验证码，在POST请求中提交验证码。</p>
<p>recaptcha返回的是一段recaptcha自己风格的html片段，效果大家参考twitter的验证码，实际上是一个iframe，iframe的url中包含了哈希串。其中的字段名也自然被写死成recaptcha_challenge_field和recaptcha_response_field，考虑到应用服务器无需验证这两个field的输入，所以也无可厚非。recaptcha_response_field用于输入字符，recaptcha_challenge_field在载入时被修改为一个唯一key。</p>
<p>提交验证时，recaptcha需要提供以上两个用户输入和应用的privatekey以及浏览器ip。recaptcha通过recaptcha_challenge_field 应用的private key以及用户出口ip可以唯一标示用户，并包含一些冗余实现安全相关策略。</p>
<h3>Vidoop</h3>
<p>Vidoop提供的服务机制与recaptcha大同小异</p>
<pre class="brush:python">
customer_id = "***"
site_id = "localtest"
api_username = "******"
api_password = "******"
vdp = VidoopSecure(api_username, api_password, customer_id, site_id)

class Vidoop(object):
    def GET(self):
        captcha_id, captcha_url, captcha_categories, captcha_text = vdp.create_captcha()
        return render.vidoop(captcha_id, captcha_url, captcha_categories, captcha_text)

    def POST(self):
        params =web.input()
        captcha_id, captcha_code = params.id, params.code
        try:
            vdp.submit_captcha(captcha_id, captcha_code)
            return True
        except:
            return False
</pre>
<p>提交验证时只需要要captcha_id和用户输入，这里相对recaptcha做了简化，但已经足够验证需要了。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e6%9c%8d%e5%8a%a1recaptcha%e5%92%8cvidoop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>验证码服务的两种方式</title>
		<link>http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e7%9a%84%e4%b8%a4%e7%a7%8d%e6%96%b9%e5%bc%8f/</link>
		<comments>http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e7%9a%84%e4%b8%a4%e7%a7%8d%e6%96%b9%e5%bc%8f/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 13:55:38 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[手艺]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=260</guid>
		<description><![CDATA[方式1，应用服务器负责生成验证码字符，验证码服务器主要负责验证码图片生成。 用户浏览器向应用服务器请求包含验证码的页面； 应用服务器生成验证码字符，存储在session中；应用服务器发送相关图片参数（验证码字符、宽、高、复杂度、背景色等）到验证码服务器； 验证码服务器返回图片地址到应用服务器； 应用服务器将包含验证码地址的网页发送给用户浏览器； 用户浏览器通过img的src方式向验证码服务器请求验证码图片； 验证码服务器输出验证码图片流到用户浏览器； 用户判读验证码图片，提交表单； 应用服务器取出session中的验证码字符比对，返回结果。 这种方式的优点： 较少的HTTP请求调用 替换原应用中独立的验证码功能相对容易 验证码服务器相对简单 方式2，验证码服务器承担验证功能，应用服务器在验证中仅起到传递作用。 用户浏览器向应用服务器请求包含验证码的页面； 应用服务器发送相关图片参数（宽、高、复杂度、背景色等）到验证码服务器； 验证码服务器返回图片地址、惟一的会话id到应用服务器； 应用服务器将包含验证码地址的网页发送给用户浏览器； 用户浏览器通过img的src方式向验证码服务器请求验证码图片； 验证码服务器输出验证码图片流到用户浏览器； 用户判读验证码图片，提交表单； 应用服务器将第三步获得的会话id和用户输入的验证码字符传给验证码服务器； 验证码服务器进行验证，返回通过或拒绝； 应用服务器根据验证码服务器结果进行响应。 这种方式的优点： 验证码服务功能完善，涵盖整个验证流程； 验证码服务端有详细的验证日志记录，便于数据分析； 欢迎大家就两种方式发表意见～]]></description>
			<content:encoded><![CDATA[<h3>方式1，应用服务器负责生成验证码字符，验证码服务器主要负责验证码图片生成。</h3>
<p><img class="alignnone" src="http://farm3.static.flickr.com/2624/4005000566_e100e098ef.jpg" alt="" width="500" height="310" /></p>
<ol>
<li>用户浏览器向应用服务器请求包含验证码的页面；</li>
<li>应用服务器生成验证码字符，存储在session中；应用服务器发送相关图片参数（验证码字符、宽、高、复杂度、背景色等）到验证码服务器；</li>
<li>验证码服务器返回图片地址到应用服务器；</li>
<li>应用服务器将包含验证码地址的网页发送给用户浏览器；</li>
<li>用户浏览器通过img的src方式向验证码服务器请求验证码图片；</li>
<li>验证码服务器输出验证码图片流到用户浏览器；</li>
<li>用户判读验证码图片，提交表单；</li>
<li>应用服务器取出session中的验证码字符比对，返回结果。</li>
</ol>
<p>这种方式的优点：</p>
<ol>
<li>较少的HTTP请求调用</li>
<li> 替换原应用中独立的验证码功能相对容易</li>
<li> 验证码服务器相对简单</li>
</ol>
<h3>方式2，验证码服务器承担验证功能，应用服务器在验证中仅起到传递作用。</h3>
<p><img class="alignnone" src="http://farm3.static.flickr.com/2464/4005000760_cc402da4c1.jpg" alt="" width="500" height="310" /></p>
<ol>
<li>用户浏览器向应用服务器请求包含验证码的页面；</li>
<li>应用服务器发送相关图片参数（宽、高、复杂度、背景色等）到验证码服务器；</li>
<li>验证码服务器返回图片地址、惟一的会话id到应用服务器；</li>
<li>应用服务器将包含验证码地址的网页发送给用户浏览器；</li>
<li>用户浏览器通过img的src方式向验证码服务器请求验证码图片；</li>
<li>验证码服务器输出验证码图片流到用户浏览器；</li>
<li>用户判读验证码图片，提交表单；</li>
<li>应用服务器将第三步获得的会话id和用户输入的验证码字符传给验证码服务器；</li>
<li>验证码服务器进行验证，返回通过或拒绝；</li>
<li>应用服务器根据验证码服务器结果进行响应。</li>
</ol>
<p>这种方式的优点：</p>
<ol>
<li>验证码服务功能完善，涵盖整个验证流程；</li>
<li> 验证码服务端有详细的验证日志记录，便于数据分析；</li>
</ol>
<p>欢迎大家就两种方式发表意见～</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/10/%e9%aa%8c%e8%af%81%e7%a0%81%e7%9a%84%e4%b8%a4%e7%a7%8d%e6%96%b9%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

