动易CMS验证码图片数据分析采集

Posted by Joseph Han on 2011-07-10

转载请注明来源:Blog of Joseph Han

最近需要实现一个识别动易CMS系统图片认证码的功能.

基本思路是:

1.先获取认证码所有字符图片的特征码;

2.解析出要识别的验证图片的6个字符的特征码;

3.取一个要识别的字符的特征码,与所有的字符特征码进行相似度计算,选最大的那个就是识别出的字符.

4.将步骤3重复6次,识别出一个验证图片的所有验证码

 

基础工作就是采集出所有字符图片的特征码

我要采集的这个网站使用的是彩色背景的图片验证码,没有噪声.

所以采集很方便,图片是24位色BMP格式的.

按像素读取每一个点,判断是否是黑色(RGB0x000000)

是黑色记录1,不是记录成0

每幅图片6个字符,像素数据是逐行记录到数据的,所以要按每个字符的宽带(10像素)分成6个数组记录

机器识别完成后,人工识别输入正确的验证码.

根据人工识别的内容把特征码依次存入文件

 

全部代码如下

<?php
error_reporting(0);
define(“CODE_SIZE”,6);
define(“HEAD_SIZE”,0x36);
define(“WIDTH”,10);
define(“HEIGHT”,15);
// 初始化一个 cURL 对象
$curl = curl_init();

// 设置你需要抓取的URL
curl_setopt($curl, CURLOPT_URL, ‘http://www.xxxxx.com/inc/checkcode.asp’);

// 设置header
curl_setopt($curl, CURLOPT_HEADER, false);

// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$all_code=“01234567890abcdefghijklmnopqrstuvwxyz”;
$arr_code=array();
for($i=0;$i<36;$i++){
$word=substr($all_code,$i,1);
if(file_exists("{$word}.txt"))
$arr_code[$word]=true;
}
while(count($arr_code)<36){
// 运行cURL,请求网页

$code_data = curl_exec($curl);
$fin = fopen(“tmp.bmp”,“w+b”);
fwrite($fin ,$code_data);
$data=array();
fseek($fin,HEAD_SIZE);
for($i=0;$i<HEIGHT;$i++)
for($j=0;$j<CODE_SIZE;$j++)
for($k=0;$k<WIDTH;$k++){
$tmp = unpack(“H6”,fread($fin,3));
if($tmp[1]==“000000”)
$data[$j].=“1”;
else
$data[$j].=“0”;
}
fseek($fin,HEAD_SIZE);
echo(“图片解析完毕,内容如下:\n”);
$all="";
for($i=0;$i<HEIGHT;$i++){
$line="";
for($j=0;$j<CODE_SIZE*WIDTH;$j++){
$tmp = unpack(“H6”,fread($fin,3));
if($tmp[1]==“000000”)
$line.=“■”;
else
$line.=“□”;
}
$all=$line."\n".$all;
$line="";
}
echo($all.“请输入人工识别出的字符:”);
$code = fgets(STDIN);
if($code=="\n")continue;
for($i=0;$i<6;$i++){
$word = substr($code,$i,1);
if(!isset($arr_code[$word])){
$fout = fopen("{$word}.txt",“wb”);
fwrite($fout,$data[$i]);
fclose($fout);
$arr_code[$word]=true;
}
}
}
echo(“36个字符全部都获得了:)\n”);
// 关闭URL请求
curl_close($curl);
?>