神经网络的Javascript实现:Jaccount验证码识别-chrome插件

less than 1 minute read

Published:

大家是不是已经厌烦了每次登陆教学信息服务网的时候,总是要输入验证码还有可能打错?

我和柱子一起写了一个 Chrome 插件,解放你的双手,让你放飞自我(?),从此跟 Jaccount 登陆页面说再见。

点击这里下载压缩包,使用方法在本文最后。 插件很快就会上线 Chrome 网上应用商店,届时也可以选择直接从商店安装。

项目放在了 GitHub 页面上,没有后门,大家可以点击Jaccount-Captcha到我们的项目页面中查看源代码。

正文

还记得前段时间我用matlab写过对一卡通网站的验证码识别,虽说识别效果很好,但不太实用。 因为那个网站基本上没什么人用。。。然后就想,大家登陆的最多的是什么?那肯定是 Jaccount 啊。于是就萌生了这个写插件的想法。

之前我也提到过,Jaccount 的验证码很好识别。用 Python 直接就能调用现成的库来对验证码进行破解。我之前用的就是Tesseract,识别正确率已经很高了。 但是,那只是 Python 啊。日常使用,不可能上个网还要打开一个 python 脚本吧,那倒不如自己输验证码。用插件的好处就是,你安装好之后,他可以像不存在一样,无缝链接页面,让你完全不用管登陆界面。

但是 JavaScript 写起来没有 Python 那么方便。没有那么多库可以调用,所以基本上就等于全部自己写一遍。

流程介绍

图片预处理

图片预处理的部分跟我上一篇文章提到的一样,流程为 1. 图片转灰度 2. 去噪 3. 二值化 4. 分割字符 5. 转成大小相同的向量

下图是我用 Python 爬的训练集。

从图上可以看出 Jaccount 验证码的一个好处就是他没有噪点,因此省略掉了去噪这一步。但是不好的地方在于,每张图片中每个字母出现的位置是不确定的,而且字母的个数也是不定的。因此此处需要修改分割字符的算法。

要注意的是在 JavaScript 里面不能直接对image获取它的像素矩阵。我的处理办法是先构建一个canvas,在canvas上绘制img,然后再读取canvas的像素信息。

caCanvas = document.createElement("canvas");
document.body.appendChild(caCanvas);
captcha = document.getElementsByTagName('img')[1];
caCanvas.width = captcha.naturalWidth;
caCanvas.height= captcha.naturalHeight;
ctx = caCanvas.getContext('2d');
ctx.drawImage(captcha, 0, 0);
imgData = ctx.getImageData(0,0,caCanvas.width,caCanvas.height).data;

得到的imgData就是RGB像素向量了,随后根据他的规则自行转化成矩阵即可。接下来就是分割,分割的原理很简单,先对图片进行扫描。

具体的扫描算法大家可以参考源码,这里就不贴了。简单来说就是对行列进行叠加,出现峰的地方就是一个字符。下面是我测试的分割的结果。

分割之后,每张图片的大小都是不一样的,所以得先统一转成25×20px的大小,然后再重排成一维数组,输入到神经网络里面。 得到的返回结果就是每个字母的概率,然后选取概率最大的输出即可。

插件的使用方法

压缩文件安装

先在 Chrome 中打开拓展程序管理的页面。

选择“加载已解压的拓展程序

这时候你浏览器右上角已经多了一个符号,这表明插件已经安装成功了。

这时候点击一下图标,在弹出窗口内输入你的账号密码,点确定。到这里,插件已经全部配置成功了,现在只要打开Jaccount 登陆页面,就会自动登录。

赶紧去测试一下吧!

关于账号密码的存放,是存放在chrome的本地,所以大家不用担心安全问题。具体代码如下:

chrome.storage.sync.set({'user': localUser.value}, function(result) {
	console.log("保存成功")});
chrome.storage.sync.set({'pwd': localPwd.value}, function(result) {
    window.close();
});

如遇到什么使用上的问题和插件的 bug,可以联系我或者柱子。

希望大家体验愉快!