聊聊图片验证

  昨天为了实现一个很好玩的应用而不得不花将近两个小时的时间破解了一个网站的登录图片验证,现记录心得如下:)

  这个图片验证属于特别规整的那种,除了在背景上加了些跟文字同色的干扰点之外,内容全部为数字,数字的颜色固定,数字的位置固定,数字本身没有经过变形,所以特别容易下手:)

  识别图片中的文字首先肯定要排除干扰因素,一开始想到了一种方法——扫描图片,去掉面积小于 3 的色块(把一个象素点的面积算作 1)。其实基本上这种办法是完全可行的,因为数字的笔划都是连续的,所以面积肯定不小,这样一来面积小的色块就一定是干扰点啦。但是对于跟数字连在一起的干扰点,这种方法无效。去掉干扰点之后就可以通过取一些特征点判断出是那个数字了。

  但是后来想到的另外一种更简单有效的方法立刻让我打消了实现上述方法的念头。那就是:取到所有 10 个数字的字模(点阵信息)保存在程序里,之后把每一个待识别数字跟字模进行比较,只要其中任何一个象素不符合就表示不是这个数字。这样一来就根本不用管图片上的干扰点啦:D

  由于认证图片中的数字位置固定,所以可以先多保存几个认证图片,用程序把每个数字单独切分保存。当积累到一定数量的样本之后就可以采集字模啦(我每个数字采集了 4 张样本图)。

  取字模也用程序实现,只要挨个扫描样本,取前景色象素的交集就可以得到字模。现在取到了字模,图片中每个数字的位置又是固定的,只要按照上面说的思路写段非常简单的图片跟字模比较的代码就可以实现认证图片识别啦(完全不用管图片中的干扰点!)。程序写好后做了一下测试,可以百分之百识别该网站认证图片中的内容,哈哈!

  从这个破解过程中得到一些关于好的认证图片生成算法的特征:
* 文字颜色、干扰颜色跟背景颜色要随机产生
* 文字位置和文字间距也要随机调整
* 文字要做旋转和变形
* 如果用汉字的话,效果会更好:)(当然,不适用于国际化网站)

  做了如上处理的认证图片,基本上应该是很难被程序识别啦,除非你用那些深奥如模式识别或者什么神经网络算法吧?!这里有个例子,不知是真是假:)

Leave a Reply