作者:Adam Geitgey

机器之心编译

参与:李泽南、蒋思源

php破解验证码应用OpenCVKeras轻松破解验证码 Webpack

登录网站时必须输入的图片验证码可以用来识别访问者到底是人还是机器——这同时也是某种程度上的「图灵测试」,人工智能研究者们寻求破解的方向,让打算机学会破解验证码,我们就间隔通用智能更近了一步(前不久 Vicarious 揭橥在 Science 上的论文就先容了一种用于破解图片验证码的机器学习新模型)。
本日,破解全天下最为盛行的图片验证码须要多久?本文作者 Adam Geitgey 见告你:仅需 15 分钟。

每个人都讨厌 CAPTCHA——这些恼人的图片中包含你必须输入的笔墨,精确地填写它你才能访问网站。
CAPTCHA 全称「全自动区分打算机和人类的公开图灵测试(Completely Automated Public Turing test to tell Computers and Humans Apart)」,旨在确认访问者是真正的人类,防止恶意程序的入侵。
然而,随着深度学习和打算机视觉技能的发展,现在这些认证方法可以被我们轻松破解了。

最近,我正在读 Adrian RoseBrock 撰写的《Deep Learning for Computer Vision with Python》。
在这本书中,Adrian 利用机器学习破解了 E-ZPass New York 网站上的 CAPTCHA 验证码:

在这里,Adrian 没有接入天生 CAPTCHA 图片运用源代码的权限。
为了破解这样的系统,我们必须找到数百张示例图片,然后演习机器学习模型来破解它。

但是如果我们想要破解开源的 CAPTCHA 系统——在这里我们拥有所有源代码的访问权,事情又会如何呢?

我访问了 http://WordPress.org (http://wordpress.org/) 插件登记网站,在个中搜索「CAPTCHA」。
结果中显示的第一个内容是「Really Simple CAPTCHA」,已经拥有超过 100 万次生动安装了:https://wordpress.org/plugins/really-simple-captcha/。

重点在于,这里有它的源代码!
有了天生 CAPTCHA 图片的源代码,我们就可以轻松破解验证码了。
在这里,为了让任务更具寻衅性,我们先给自己添加一点限定:我们能不能在 15 分钟内破解它?Let's try it!

Note:这并不虞味着我们在批评「Really Simple CAPTCHA」插件及其作者。
目前,插件的作者已表示该款验证码已经不再安全,并推举用户探求其他更加具有安全性的认证办法。
但如果你真的是这 100 万用户中的一员,或许你该当有所防备了:)

寻衅

首先,我们须要做好操持,让我们看看 Really Simple CAPTCHA 天生的图片是什么样子。
在 Demo 站中,我们看到了这样的情景:

一个 CAPTCHA 图片范例

看起来它会天生由四个字符组成的图片。
让我们在这个插件的 PHP 源代码里面确认一下:

public function __construct() { / Characters available in images / $this->chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; / Length of a word in an image / $this->char_length = 4; / Array of fonts. Randomly picked up per character / $this->fonts = array( dirname( __FILE__ ) . '/gentium/GenBkBasR.ttf', dirname( __FILE__ ) . '/gentium/GenBkBasI.ttf', dirname( __FILE__ ) . '/gentium/GenBkBasBI.ttf' );复制代码

没错,它会天生四个字母/数字组成的 CAPTCHA 验证码,每个字符的字体各不相同,在代码中我们也可以看出验证码中不会包含「O」或者「I」,由于这两个字母很可能会让人与数字产生稠浊。
以是,我们共有 32 个数字或字母须要识别。
没问题!

至此用时:2 分钟

我们须要的工具

在开始破解之前,我们先要先容一下行动所需的工具:

Python 3

Python 是目前人工智能领域中最为盛行的编程措辞,包含多种机器学习和打算机视觉库。

OpenCV

OpenCV 是打算机视觉和图像处理任务上的盛行框架。
在这里,我们须要利用 OpenCV 来处理 CAPTCHA 天生的图像,OpenCV 拥有 Python API,以是我们可以直策应用 Python 调用它。

Keras

Keras 是一个利用 Python 编写的深度学习框架。
他可以让我们更加轻松地定义、演习和利用深度神经网络——仅需编写很少的代码。

TensorFlow

TensorFlow 是谷歌推出与掩护的机器学习库,也是目前人工智能领域里最为盛行的框架。
我们会在 Keras 之上写代码,但 Keras 实际上并没有实现神经网络运算的方法——它须要利用 TensorFlow 作为后端来完成详细的事情。

好了,让我们回到寻衅之中。

创立数据集

想要演习任何机器学习系统,我们都须要相应的数据集。
为了破解 CAPTCHA 验证码系统,我们须要这样的演习数据:

看起来少不了大量的标注事情。
不过在这里我们有了 WordPress 插件的源代码,我们可以稍稍修正插件,让它自动输出 10,000 个 CAPTCHA 图片,以及相应的精确答案。

在对源代码的几分钟破解之后(只要大略地加个『for』循环),我们就拥有了一个内含 10,000 张 PNG 图片的演习集,而图片的精确答案便是每张图片的文件名:

Note:在这部分我不会给你示例代码。
由于本文面向传授教化,希望各位不会真的去破解各家 WordPress 网站。
不过这里我会给你 10,000 张天生的图片让大家用于复现。

至此用时:5 分钟

简化问题

现在我们已经有了演习数据,我们可以直接用它来演习一个大略的神经网络:

由于有了足够的数据,这种方法将能很好地事情,但我们可以使问题变得更大略。
由于问题越大略、演习数据越少,我们办理问题所须要的打算力就越少,毕竟我们统共只有 15 分钟的韶光。

幸运的是,一个 CAPTCHA 图像由四个符合组成,因此我们可以以某种办法将图像分割开以令每张图像只有一个符号。
这样的话我们只需演习神经网络识别单个字符就行了。

我们并不能手动地用 Photoshop 等图像软件将它们分割开,由于演习图像统共有 1 万张。
此外,我们也不能将图像切分为四个等大小的图像块,由于 CAPTCHA 会随机地将这些不同的字符放置在不同的水平线上,如下所示:

幸运的是,我们能利用已有的方法自动完成这一部分。
在图像处理中,我们常常须要检测有相同色彩的像素块,这些连续像素块的边界可以称之为轮廓。
而 OpenCV 有一个内置的 findContours() 函数可以检测这些轮廓的区域。

以是我们原始的 CAPTCHA 图像为如下所示:

然后我们将该图像转换为纯净的黑白像素点(即采取色彩阈值的方法),因此我们将很随意马虎探求到连续的轮廓边界:

下面我们利用 OpenCV 的 findContours() 函数以检测包含连续相同像素块的分离部分:

随后将每个区域保存为一个单独的图像文件就非常大略了,而且我们也知道每张图像从左到右有四个字符,因此我们可以在保存的时候利用这种知识标注各个字符。
我们只须要按顺序保存它们,并将每一张图像保存为对应的字符名。

但是还有一个问题,有些 CAPTCHA 图像包含重叠的字符:

这就意味着我们很可能会将两个字符抽取为一个分割区域:

如果我们不办理这个问题,那么我们末了就会创建一个非常糟糕的演习集。
我们须要办理这个问题,以免模型会将两个重叠的字符识别为一个。

这里有一个大略的办理方案,如果字符轮廓的宽要比高长一些,那么很有可能这一个切分内就包含了两个字符。
因此我们可以将这种连体的字符拆分为两半,并将它们视为单独的字符。

我们将宽度大于高度一定数值的图像拆分为两个数值,虽然这种方法非常大略,但在 CAPTCHA 上却十分有效。

现在我们有方法抽取独立的字符,因此我们须要将所有的 CAPTCHA 图像都实行这种处理。
我们的目标是网络每个字符的不同变体,并将单个字符的所有变体保留在一个文件夹中。

上图展示了字符「W」的抽取情形,我们末了从 1 万张 CAPTCHA 图像中获取了 1147 张不同的「W」。
处理完这些图像后,我们统共大约花了 10 分钟。

构建并演习神经网络

由于我们一次只须要识别单个字符,以是并不须要一个繁芜的神经网络架构,且识别这种字母与数字的任务要比其它识别繁芜图像的任务大略地多。
因此我们利用了一个大略的卷积神经网络,它一共包含两个卷积层与两个全连接层。

如果我们利用的是 Keras,那么只须要几行代码就能构建一个神经网络架构:

# Build the neural network!model = Sequential()# First convolutional layer with max poolingmodel.add(Conv2D(20, (5, 5), padding=\公众same\公众, input_shape=(20, 20, 1), activation=\"大众relu\公众))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))# Second convolutional layer with max poolingmodel.add(Conv2D(50, (5, 5), padding=\"大众same\"大众, activation=\"大众relu\"大众))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))# Hidden layer with 500 nodesmodel.add(Flatten())model.add(Dense(500, activation=\"大众relu\公众))# Output layer with 32 nodes (one for each possible letter/number we predict)model.add(Dense(32, activation=\公众softmax\公众))# Ask Keras to build the TensorFlow model behind the scenesmodel.compile(loss=\"大众categorical_crossentropy\"大众, optimizer=\公众adam\"大众, metrics=[\"大众accuracy\"大众])复制代码

现在开始演习

# Train the neural networkmodel.fit(X_train, Y_train, validation_data=(X_test, Y_test), batch_size=32, epochs=10, verbose=1)复制代码

在经由 10 个 Epoch 的演习后,我们的演习准确度可以到达 100%,因此我们就能终止程序以完玉成部模型的演习。
以是末了我们一共花了 15 分钟。

利用演习后的模型办理 CAPTCHA 识别问题

现在我们利用已演习的神经网络可以轻松识别 CAPTCHA 验证码:

在网站上利用 WordPress 插件获取真正的 CAPTCHA 验证码;将 CAPTCHA 图像分割为四个独立的字符块,这里利用的方法和创建演习集的方法一样;调用神经网络对这四个独立的字符块进行预测;将四个预测结果排列以作为该 CAPTCHA 验证码的返回结果。

或者我们可以直策应用命令走运行:

试试看!

如果你想自己试验一下,这里有代码:https://s3-us-west-2.amazonaws.com/mlif-example-code/solving_captchas_code_examples.zip

这个压缩文件包中包含 10,000 张实例图片以及本文中涉及的每一步的代码。
个中还有 README 文件见告你如何运行它。

如果你想要深入理解代码背后的知识,那么最好读一读那本《Deep Learning for Computer Vision with Python》。
它涵盖了很多细节,并先容了大量示例,如果你对办理现实生活中困难问题的示例感兴趣,那么它或许很适宜你。

原文链接:medium.com/@ageitgey/h…