ホームページ >バックエンド開発 >PHPチュートリアル >非常に簡単な PHP 検証コードの識別

非常に簡単な PHP 検証コードの識別

藏色散人
藏色散人転載
2021-04-27 11:20:213913ブラウズ

この記事では、非常に簡単な PHP 検証コードの識別方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

Web サイトのログイン ページや登録ページなど、いたるところに確認コードが表示されていますが、その確認コードは本当に安全なのでしょうか。おそらく、必要なのは単純な小さなプログラムだけであり、検証コードは偽物のようなものになるでしょう。この記事は単なる実装であり、あまり深くは説明しません。

攻撃があるところには防御もあります

私がこの記事を書いたのは、同僚の公開アカウントが「検証コードの作成の練習」という記事を投稿したからです。あなたはそれを簡単に書きました、そして私はシンプルに解読してみてください。人生は楽しいことでいっぱいです~

検証コードの生成

コードをコピーして実行し、次の検証コードを生成します:

非常に簡単な PHP 検証コードの識別

##図に示すように、この確認コードの形式は非常に「標準的」であることがわかります。フォント サイズは同じで、色は黒なので、多くの手間が省けます。

二値化

プログラムは画像を読み取って二値化します(重要な点はフォント色の閾値を見つけることです。この検証コードはすべて黒なので...)、1ピクセルプログラムにより1ピクセルを判定し、フォントの色を*、フォント以外の色を0

非常に簡単な PHP 検証コードの識別

上図より, 大まかに確認コード (

YTAD) が確認できます

画像を分析し、

を切り取って文字列を切り出します (最初に緑色の線を切り取ります)を選択し、青い線を個別にカットします。これにより、この文字が上下に移動しても、カットに影響しにくくなります)

非常に簡単な PHP 検証コードの識別#機能コードの抽出

文字列を分割した後、検証コードを複数回取得し、a-z、A-Z、0-9、およびその他の検証コードのすべての機能コードを記録します。

これは抽出された文字 非常に簡単な PHP 検証コードの識別Y

認識

認識処理は二値化→切り出し→特徴コード抽出を繰り返し、前回抽出した特徴コードとの類似度を比較すればOKです。

PHP コードの実装

/**
 * 简单验证码识别
 * @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);
*/
実行結果:

以上が非常に簡単な PHP 検証コードの識別の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。