分享 12306 验证码简单识别

debbbbie · 2013年12月22日 · 最后由 blackanger 回复于 2013年12月22日 · 8761 次阅读

12306 的图形验证码非常简单,简单的程序即可识别。

1-1

利用 photoshop 的色调分离技术,即可得到辨识度很高的图片。 色调分离很容易实现,比如当参数为 3 时,会把图片红蓝绿每个通道简化成 3 个颜色值, 并最终形成 3 x 3 = 9 个颜色值。

1-2

然后配上简单的优化,即把没有上下相邻都没有颜色的点排除掉。 1-3

将此图片交给 Tesseract-OCR,10% 的识别率有木有。

10% 的合格率已经合格了哟,配上代理服务器,还有 gem useragents。。。

附 色调分离的代码实现( python 版)

def color_sep(img, count=3):

    min, max = [127, 127, 127], [128, 128, 128]
    w, h = img.size

    pix = img.load()
    for x in xrange(w):
        for y in xrange(h):
            if max[0] < pix[x, y][0]: max[0] = pix[x, y][0]
            if max[1] < pix[x, y][1]: max[1] = pix[x, y][1]
            if max[2] < pix[x, y][2]: max[2] = pix[x, y][2]

            if min[0] > pix[x, y][0]: min[0] = pix[x, y][0]
            if min[1] > pix[x, y][1]: min[1] = pix[x, y][1]
            if min[2] > pix[x, y][2]: min[2] = pix[x, y][2]

    deep_color   = [(max[0] - min[0]) * 1.0 / count, (max[1] - min[1]) * 1.0 / count, (max[2] - min[2]) * 1.0 / count]
    target_color = [255.0 / (count - 1), 255.0 / (count - 1), 255.0 / (count - 1)]

    for x in xrange(w):
        for y in xrange(h):
            pix[x, y] = ( int(int((pix[x, y][0] - min[0]) / deep_color[0]) * target_color[0]), \
                    int(int((pix[x, y][1] - min[1]) / deep_color[1]) * target_color[1]), \
                    int(int((pix[x, y][2] - min[2]) / deep_color[2]) * target_color[2]) )

实验结果,采集途径北京北站的火车

1-5

[声明]:此文仅为技术探讨贴,并已提交至 http://WooYun.org,请勿跨省 = =!

为啥提交给乌云啊 ...

tweak 一下,应该能达到大约 50% 的正确率

#2 楼 @bhuztez 希望 12306 重视一下?等抢票软件少了,我们购票或许会更流畅

#3 楼 @debbbbie 10% 人家都懒得理你啊。而且验证码难度越高对屌丝越不利吧 ...

全搞成 recaptcha 那种奇葩的,人都三次错两次的,软件 tweak 得好识别率反而比人高 ..

#4 楼 @bhuztez 识别率可以提高,只要再深入挖掘下就有了。。。 不过 12306 真是高端大欺上档次,不但不鸟我,连国内众多浏览器也一并不鸟

@debbbbie 有个问题,每次请求过去,12306 的验证码不会改变吗? 意思就是第一次请求过去获取了识别码,验证完毕之后,自动登录提交的时候发现识别码已经换成另一个了,之前我碰到过类似的问题,但不是 12306。

#7 楼 @blackanger 嗯嗯,没有变,一次验证码估计起码能撑几分钟

反机器最有效还是 pow 表单

#9 楼 @blackanger 就算重新生成也能匹配的 我之前做的是这样的 就是页面上看到的是一个验证码 程序生成了另一个验证码 直接提交就行了

#11 楼 @zj0713001 我碰到的情况是不行的,我识别的验证码和网站要验证的验证码,正好错位了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号