<?php
/**
* 破解图片验证码
* 一、要求图片没有背景,没有杂点。
* 二、图片上的数字和字母字体大小不随机改变,不扭曲,对颜色没要求
* 三、通过对$charconfig配置的修正,可以让程序学会认识更多的数字和字母。本程序仅以chinaunix.net的数字验证码为例
*
* @author superspice
yeah.net
*/
/* 0-9数字的点阵配置 */
$charconfig = array("9" => array('1,1','1,1,1,1,0,0,1,1','1,1,0,0,1,1,0,0,1,1',
'1,0,0,0,0,1,0,0,0,1','1,0,0,0,0,1,0,0,0,1','1,1,0,0,1,0,0,0,1,1','1,1,1,1,1,1,1,1','1,1,1,1,1,1'),
"8" => array('1,0,0,0,1,1','1,1,1,0,1,1,1,1','1,1,0,1,1,1,0,0,1,1',
'1,0,0,0,1,0,0,0,0,1','1,0,0,0,1,0,0,0,0,1','1,1,0,1,1,1,0,0,1,1','1,1,1,0,1,1,1,1','1,0,0,0,1,1'),
"7" => array('1,0,0,0,0,0,0,0,1,1','1,0,0,0,0,0,0,1,1,1',
'1,0,0,0,0,0,1,1','1,0,0,0,0,1,1','1,0,0,0,1,1','1,0,0,1,1','1,1,1,1','1,1,1'),
"6" => array('1,1,1,1,1,1','1,1,1,1,1,1,1,1','1,1,0,0,0,1,0,0,1,1',
'1,0,0,0,1,0,0,0,0,1','1,0,0,0,1,0,0,0,0,1','1,1,0,0,1,1,0,0,1,1','1,1,0,0,1,1,1,1','1,1' ),
"5" => array('1,1,1,1,1,0,0,1','1,1,1,1,1,0,0,1,1','1,0,0,0,1,0,0,0,1,1',
'1,0,0,1,0,0,0,0,0,1','1,0,0,1,0,0,0,0,0,1','1,0,0,1,1,0,0,0,1,1','1,0,0,0,1,1,1,1,1','1,1,1'),
"4" => array('1,1','1,1,1','1,1,0,1','1,1,0,0,1','1,1,0,0,0,1',
'1,1,1,1,1,1,1,1,1,1','1,1,1,1,1,1,1,1,1,1','1'),
"3" => array('1,0,0,0,0,0,0,1','1,1,0,0,0,0,0,0,1,1','1,0,0,0,0,0,0,0,0,1',
'1,0,0,0,1,0,0,0,0,1','1,0,0,0,1,0,0,0,0,1','1,1,0,1,1,1,0,0,1,1','1,1,1,0,1,1,1,1','1,0,0,0,1,1'),
"2" => array('1,0,0,0,0,0,0,1','1,1,0,0,0,0,0,1,1','1,1,0,0,0,0,0,1,1,1',
'1,0,0,0,0,0,1,1,0,1','1,0,0,0,0,1,1,0,0,1','1,1,0,0,1,1,0,0,0,1','1,1,1,1,0,0,0,0,1','1,1,0,0,0,0,0,1'),
"1" => array('1,0,0,0,0,0,0,1','1,1,0,0,0,0,0,0,1','1,1,1,1,1,1,1,1,1,1',
'1,1,1,1,1,1,1,1,1,1','1','1'),
"0" => array('1,1,1,1','1,1,1,1,1,1','1,1,0,0,0,0,1,1','1,1,0,0,0,0,0,0,1,1',
'1,1,0,0,0,0,0,0,1,1','1,1,0,0,0,0,1,1','1,1,1,1,1,1','1,1,1,1')
);
/* 定义图片文件名,并根据尺寸遍历整个图片上的所有像素点,生成点阵数组 */
$image = "1317.png"; // 文件名也可以用[url]http://bbs.chinaunix.net/seccode.php[/url]这样的url
$size = getimagesize($image);
$im = imagecreatefrompng($image);
$width = $size[0];
$height = $size[1];
for($x = 1; $x < $width; $x ++)
{
$flag[$x] = false;
for($y = 1; $y < $height; $y ++)
{
$color = imagecolorat($im, $x, $y);
if($color > 0 && $flag[$x] == false)
{
$flag[$x] = true;
}
if($flag[$x] == true)
{
$col[$x][] = $color;
}
}
}
/* 去末尾空白 */
foreach($col as $k => $v)
{
$col[$k] = delbackzero($v);
}
/* 分字,前提是:字符在竖向没有重叠部分 */
$n = 0;
foreach($col as $k => $v)
{
$tmparray[] = join(",", $v);
if(is_array($col[$k-1]) && !is_array($col[$k+1]))
{
$n ++;
$char[$n] = $tmparray;
$tmparray = array();
}
}
/* 认字 */
foreach($char as $numorder => $pixelarray)
{
$thischar .= recog($pixelarray);
}
/* 输出显示 */
echo $thischar;
/****************** 以下是函数部分 ****************/
/**
* 根据字符点阵配置文件认出字符
*
* @author superspiceyeah.net
* @param array $pixelarray 字符块的点阵数组
* @global array $charconfig 点阵配置数组
* @return string 返回字符块点阵对应的字符
*/
function recog($pixelarray)
{
global $charconfig;
foreach($charconfig as $char => $pixel)
{
if($pixel == $pixelarray)
{
return $char;
break;
}
}
}
/**
* 去除竖向点阵末尾为空的部分
*
* @author superspiceyeah.net
* @param array $array 竖向宽度为1像素的图片点阵数组
* @return array 去除掉末尾连续的空白后的点阵数组
*/
function delbackzero($array)
{
foreach($array as $k => $v)
{
$array[$k] = ($v == 0) ? 0 : 1;
}
$count = count($array);
for($i = $count-1; $i >= 0; $i --)
{
if($array[$i] > 0) break;
if($array[$i] == 0 && $array[$i-1] == 0)
{
$zeroarray = array_pop($array);
}
}
$zeroarray = array_pop($array);
return $array;
}
?>