您的位置:PHPUU > PHP教程 > 实用PHP源码 > 文章内容

用php破解验证码图片

时间:2009-02-27   浏览次数 585
<?php
/**
* 破解图片验证码
* 一、要求图片没有背景,没有杂点。
* 二、图片上的数字和字母字体大小不随机改变,不扭曲,对颜色没要求
* 三、通过对$charconfig配置的修正,可以让程序学会认识更多的数字和字母。本程序仅以chinaunix.net的数字验证码为例
*
* @author      superspiceyeah.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;
}
?>
PHP教程分类