Home  >  Article  >  Backend Development  >  Extremely simple PHP verification code identification

Extremely simple PHP verification code identification

藏色散人
藏色散人forward
2021-04-27 11:20:213864browse

This article will introduce you to the super simple PHP verification code identification. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

Verification codes are everywhere on the login page, registration page, etc. of the website, but is your verification code really safe? Maybe all it takes is a simple small program, and your verification code will be like a fake. This article is just a simple implementation and will not go too deep.

Where there is offense, there is defense

I wrote this article entirely because my colleague’s public account posted an article called "Practice-Write a Verification Code". You wrote it briefly, and I Just try to crack it simply, life is full of fun~

Generate verification code

Copy the code, execute it, and generate the following verification code:

Extremely simple PHP verification code identification

As shown in the picture, we can see that the format of this verification code is very "standard". The font size is the same and the color is black, which saves us a lot of trouble.

Binarization

The program reads the image and binarizes it (the key point is to find the threshold of the font color. This verification code is all black, so...), one pixel through the program One pixel is judged, and the font color is marked as *, and the non-font color is marked as 0

Extremely simple PHP verification code identification

From the above picture, you can roughly see the verification code (YTAD)

Analyze the image and cut

to cut out the string (first cut the green line, then cut the blue line separately, so that even If this character is moved up and down, it will not easily affect our cutting)

Extremely simple PHP verification code identification

Extract feature code

After splitting the string, we obtained it multiple times Verification code, record all the feature codes of a-z, A-Z, 0-9 and other verification codes.

Extremely simple PHP verification code identification

##
This is the extracted letter

Y

Recognition

The recognition process is to repeat the above: binarization->cutting->extract feature codes, plus compare the similarity with the previously extracted feature codes, and it is OK.

PHP code implementation

/**
 * 简单验证码识别
 * @author zhjx922
 */

class vCode{

    //字符特征码
    private $_wordKeys = array (
        'A' => '000**00000****000**00**0**0000****0000****0000************0000****0000****0000**',
        'B' => '******00**000**0**0000****000**0******00**000**0**0000****0000****000**0******00',
        'C' => '00*****00**000****00000***000000**000000**000000**000000**00000*0**000**00*****0',
        'D' => '******00**000**0**0000****0000****0000****0000****0000****0000****000**0******00',
        'E' => '*********00000**00000**00000******0**00000**00000**00000**00000*******',
        'F' => '**********000000**000000**000000******00**000000**000000**000000**000000**000000',
        'G' => '00*****00**000****000000**000000**000000**000*****0000****0000**0**000**00*****0',
        'H' => '**0000****0000****0000****0000************0000****0000****0000****0000****0000**',
        'I' => '******00**0000**0000**0000**0000**0000**0000**0000**00******',
        'J' => '00****0000**0000**0000**0000**0000**0000***000****0**00***00',
        'K' => '**0000****000**0**00**00**0**000****0000****0000**0**000**00**00**000**0**0000**',
        'L' => '**00000**00000**00000**00000**00000**00000**00000**00000**00000*******',
        'M' => '**0000*****00*************0**0****0**0****0**0****0000****0000****0000****0000**',
        'N' => '**0000*****000******00******00****0**0****0**0****00******000*****000*****0000**',
        'P' => '*******0**0000****0000****0000*********0**000000**000000**000000**000000**000000',
        'Q' => '00****000**00**0**0000****0000****0000****0000****0**0****00****0**00**000****0*',
        'R' => '*******0**0000****0000****0000*********0*****000**00**00**000**0**0000****0000**',
        'S' => '0******0**0000****000000**0000000******0000000**000000**000000****0000**0******0',
        'T' => '********000**000000**000000**000000**000000**000000**000000**000000**000000**000',
        'U' => '**0000****0000****0000****0000****0000****0000****0000****0000**0**00**000****00',
        'V' => '**0000****0000****0000**0**00**00**00**00**00**000****0000****00000**000000**000',
        'W' => '**0000****0000****0000****0000****0**0****0**0****0**0*************00*****0000**',
        'X' => '**0000****0000**0**00**000****00000**000000**00000****000**00**0**0000****0000**',
        'Y' => '**0000****0000**0**00**000****00000**000000**000000**000000**000000**000000**000',
        'Z' => '*******00000**00000**0000**0000**0000**0000**0000**00000**00000*******',
        'a' => '00*****00**000**000000**0*********0000****000***0****0**',
        'b' => '**000000**000000**000000**0***00***00**0**0000****0000****0000*****00**0**0***00',
        'c' => '00*****00**000****000000**000000**0000000**000**00*****0',
        'd' => '000000**000000**000000**00***0**0**00*****0000****0000****0000**0**00***00***0**',
        'e' => '00****000**00**0**0000************0000000**000**00*****0',
        'f' => '000****000**00**00**00**00**000000**0000******0000**000000**000000**000000**0000',
        'g' => '0*****0***000*****000**0**000**00*****00**0000000******0**0000**0******0',
        'h' => '**000000**000000**000000**0***00***00**0**0000****0000****0000****0000****0000**',
        'i' => '00**0000**000000000***0000**0000**0000**0000**0000**00******',
        'k' => '**00000**00000**00000**00**0**0**00****000****000**0**00**00**0**000**',
        'l' => '***00**00**00**00**00**00**00**00**0****',
        'm' => '*0**0**0**0**0****0**0****0**0****0**0****0**0****0**0**',
        'n' => '**0***00***00**0**0000****0000****0000****0000****0000**',
        'o' => '00****000**00**0**0000****0000****0000**0**00**000****00',
        'p' => '**0***00***00**0**0000****0000****0000*****00**0**0***00**000000**000000',
        'q' => '00***0**0**00*****0000****0000****0000**0**00***00***0**000000**000000**',
        'r' => '**0****00***00**0**000000**000000**000000**000000**00000',
        's' => '0******0**0000****0000000******0000000****0000**0******0',
        't' => '00**000000**0000******0000**000000**000000**000000**000000**00**000****0',
        'u' => '**0000****0000****0000****0000****0000**0**00***00***0**',
        'v' => '**0000****0000**0**00**00**00**000****0000****00000**000',
        'w' => '**0000****0000****0**0****0**0****0**0**********0**00**0',
        'x' => '**0000**0**00**000****00000**00000****000**00**0**0000**',
        'y' => '**0000****0000****0000****0000****0000**0**00***00***0***00000**0******0',
        'z' => '******0000**000**000**000**000**0000******',
        '0' => '000**00000****000**00**0**0000****0000****0000****0000**0**00**000****00000**000',
        '1' => '00**000***00****0000**0000**0000**0000**0000**0000**00******',
        '2' => '00****000**00**0**0000**000000**00000**00000**00000**00000**00000**00000********',
        '3' => '0*****00**000**0000000**00000**0000***0000000**0000000**000000****000**00*****00',
        '4' => '00000**00000***0000****000**0**00**00**0**000**0********00000**000000**000000**0',
        '5' => '*******0**000000**000000**0***00***00**0000000**000000****0000**0**00**000****00',
        '6' => '00****000**00**0**0000*0**000000**0***00***00**0**0000****0000**0**00**000****00',
        '7' => '********000000**000000**00000**00000**00000**00000**00000**00000**000000**000000',
        '8' => '00****000**00**0**0000**0**00**000****000**00**0**0000****0000**0**00**000****00',
        '9' => '00****000**00**0**0000****0000**0**00***00***0**000000**0*0000**0**00**000****00',
    );

    /**
     * 生成验证码
     * @author 武老师
     */
    public function make($verCode = '') {
        if(empty($verCode)) {
            $baseChars     = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789';
            $verCode       = '';
            $codeCharLenth = 4;
            for ($i = 1; $i   $image,
            'code'  =>  $verCode
        );
    }

    /**
     * 获取原始图像数组
     * @param string $imageString
     * @return array
     */
    public function getImage($imageString) {
        $im = imagecreatefromstring($imageString);

        list($width, $height) = getimagesizefromstring($imageString);

        $image = array();

        for($x = 0;$x  $x) {
            if($x != ($preX + 1)) {
                $wordCount++;
            }
            $preX = $x;

            for($y = 0;$y $image) {
            $wordImage[$key] = $this->removeByLine($image);
        }


        return $wordImage;

    }

    /**
     * 按行移除无用数据
     * @param array $image
     * @return array
     */
    public function removeByLine($image) {

        $isFilter = false;
        foreach($image as $y => $yImage) {
            if($isFilter == true || array_filter($yImage)) {
                $isFilter = true;
            } else {
                unset($image[$y]);
            }
        }

        krsort($image);

        $isFilter = false;
        foreach($image as $y => $yImage) {
            if($isFilter == true || array_filter($yImage)) {
                $isFilter = true;
            } else {
                unset($image[$y]);
            }
        }

        ksort($image);

        return $image;
    }

    /**
     * 获取关键字字符串
     * @param array $wordImage
     * @return string
     */
    public function getWordString($wordImage) {
        $wordString = '';
        foreach($wordImage as $image) {
            foreach($image as $string) {
                $wordString .= $string;
            }
        }

        return $wordString;
    }

    /**
     * 匹配关键字
     * @param array $image
     * @return array
     */
    public function match($image) {
        $match = array(
            'min' => '',
            'key' => ''
        );
        foreach($this->_wordKeys as $k => $v) {
            $percent = 0.0;
            similar_text($this->getWordString($image), $v, $percent);
            if($match['min'] == '') {
                $match['min'] = $percent;
                $match['key'] = $k;
            } else {
                if($percent > $match['min']) {
                    $match['min'] = $percent;
                    $match['key'] = $k;
                }
            }
        }

        return $match;
    }

    /**
     * 终端显示验证码
     * @param $image
     */
    public function show($image) {
        foreach($image as $xImage) {
            foreach($xImage as $yImage) {
                echo $yImage;
            }
            echo PHP_EOL;
        }
        echo PHP_EOL;
    }
}


$vCode = new vCode();

$codeImage = $vCode->make();
$imageString = $codeImage['image'];

$image = $vCode->getImage($imageString);
//原图
$vCode->show($image);

//去除干扰边框、拆字
$newImage = $vCode->remove($image);
$word = array();
$code = '';
foreach($newImage as $image) {
    $vCode->show($image);
    $code .= $vCode->match($image)['key'];
}

echo "生成的验证码为:{$codeImage['code']}" . PHP_EOL;
echo "识别的验证码为:{$code}" . PHP_EOL;


/*
//用来批量生成验证码的特征码。识别他人网站验证码,需要自己采集多张,人肉标记特征码
$vCode = new vCode();

$string = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789';

$max = ceil(strlen($string) / 4);

$wordKeys = array();

for($i=0;$imake($code)['image'];


    $image = $vCode->getImage($imageString);
    $newImage = $vCode->remove($image);
    foreach($newImage as $key => $image) {
        $word = $vCode->getWordString($image);
        isset($code[$key]) && $wordKeys[$code[$key]] = $word;
    }
}

echo var_export($wordKeys);
*/

Running results:

Extremely simple PHP verification code identification

The above is the detailed content of Extremely simple PHP verification code identification. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete