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通道的格式。
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通道的格式。

今天新增的拼图验证码的可配置性非常强,你只要替换资源文件,在配置文件中修改提问的模版,指定图片的大小、行数、列数,就可以创造一套全新的验证码。他的简单程度实在超出你的想象。
Yan 新增了一种验证码类型,Web 2.0 图标验证码。用户根据图标的内容和提示的信息,提交验证码。验证码图片如下:

提示文字: Please figure out twitter icons.
用户输入Twitter图标左上角上的字母,即可进行验证。在Yan的测试界面上使用如图:

Web2.0 Icon实际上是Yan中新增的拼图验证码的一个实例,利用拼图验证码可以生成相似的更有创意的验证码。在我的开发环境中生成这样一张图片大约需要80ms。
项目中使用的图标均从互联网收集,遵循CC等协议或经作者授权,详情参考项目中README文件。
祝DAF同学生日快乐。
给Yan的验证码图片服务做了压力测试。测试环境:
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 | 421.63 | 408.11 | 326.12 |
| Time per request | 2.05 | 2.12 | 2.26 | 2.37 | 2.45 | 3.07 |
| Transfer rate | 987.91 | 955.54 | 896.85 | 854.31 | 826.25 | 660.45 |

目前对每个请求独立使用JDK的awt实时绘图,吞吐量可以达到400以上,如果稍稍优化一下Jetty的配置,性能还有一定的提升空间。这个结果还是不错的。
I will show you the usage of Yan captcha service. In this tutorial, it’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. Download the code from the project page, then build and run it with maven:
mvn jetty:run
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 http://localhost:8080/yan/reg.jsp The page is protected by HTTP Basic Authentication, the username and password are store in ‘realm.properties’ 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’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:
curl -X PUT “http://localhost:8080/yan/apikey/” -d “SinatraTestApp” -u “username:password”
If it works, you will get a line of json:
{“apikey”:”b251b0dc2eed31cac38555b61d4fa6a453923bfd”,”appName”:”SinatraTestApp”}
Save this apikey.
Sinatra is generally considered to be the world’s lightest and smallest web framework. And our application is rather simple. Just check the code:
require "rubygems"
require "sinatra"
require "net/http"
require "yaml"
apikey='b251b0dc2eed31cac38555b61d4fa6a453923bfd'
get '/' do
conn = Net::HTTP.new('localhost', 8080)
q = "ip=#{@env['REMOTE_ADDR']}&apikey=#{apikey}&alt=yaml&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']}&apikey=#{apikey}&key=#{params['key']}&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=>"/", :method=>"post"}
%p
Username:
%input{:name=>"username", :type=>"text"}
%p
Password:
%input{:name=>"password", :type=>"password"}
%p
Captcha:
%img{:src=>@ticket['url']}
%br
%input{:name=>"captcha", :type=>"text"}
%input{:name=>"key", :type=>"hidden", :value=>@ticket['key']}
%input{:type=>'submit'}
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 ‘/’. 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’s validator and return user the result. And the HAML code is template for page rendering after GET request.
Maybe you need to install sinatra and some dependency:
sudo gem install sinatra haml
Run the code with a build-in WEBrick
ruby sinatra-yan.rb
Browse to the default url, test it:

For another similar tutorial using python, check Yan’s wiki page:
http://bitbucket.org/sunng/yan/wiki/SampleCode
Thank you for your support. btw, today is my dear girl friend’s birthday, I just wish her happy everyday.