php實現簡單驗證碼識別

一直想寫這個,過了好久今天興趣來了索性記錄下。php

驗證碼

全自動區分計算機和人類的公開圖靈測試(英語:Completely Automated Public Turing test to tell Computers and Humans Apart,簡稱CAPTCHA),俗稱驗證碼,是一種區分用戶是計算機和人的公共全自動程序。在CAPTCHA測試中,做爲服務器的計算機會自動生成一個問題由用戶來解答。這個問題能夠由計算機生成並評判,可是必須只有人類才能解答。因爲計算機沒法解答CAPTCHA的問題,因此回答出問題的用戶就能夠被認爲是人類。
百科介紹

說的簡單點就是隨機生成的字符,輸出在一張圖片上[這裏不考慮其餘形式的拖拽/短信驗證碼等等]。git

常見類型

圖片描述

思路

本文只作演示使用,故取第一張圖片驗證碼做爲講解示例。
圖片描述github

圖片上的每一點都有其RGB值,經過取色器能夠獲取到,肉眼觀察能夠看出該圖驗證碼是純數字純色背景 segmentfault

圖片描述

經過取色器看出該驗證碼背景色RGB值爲(212,214,204)數組

實現

下面咱們來用PHP的imagecolorsforindex函數取得圖片全部點的RGB值:安全

$url = 'http://210.32.33.91:8080/reader/captcha.php';
$im = imagecreatefromgif($url);
imagegif($im, '1.gif');
$rgbArray = array();
$res = $im;
$size = getimagesize($url);

$wid = $size['0'];
$hid = $size['1'];
for ($i = 0; $i < $hid; ++ $i) {
    for ($j = 0; $j < $wid; ++ $j) {
        $rgb = imagecolorat($res, $j, $i);
        $rgbArray[$i][$j] = imagecolorsforindex($res, $rgb);
    }
}

結果以下:服務器

圖片描述


各位可能想問這有什麼用呢? 下面咱們換一種方式來顯示數據,爲背景色輸出,驗證碼區域輸出,再來看下:函數

for ($i = 0; $i < $hid; $i ++) {
    for ($j = 0; $j < $wid; $j ++) {
        
        if ($rgbArray[$i][$j]['red'] == 212) {
            echo '□';
        } else {
            echo '■';
        }
    }
    echo "<br>";
}

效果:
圖片描述測試

這樣一下是否是很清楚了。url

可是你可能仍是有疑問,儘管能夠看出來了,可是如何知道是多少呢?

下面咱們來分析下:
圖片描述
每一個驗證碼直接間距4格,左右間距6/10格,上下間距16/10格。

咱們再來去掉這些干擾點,能夠看得更清晰些:
圖片描述
是否是很清晰了?可能仍是有人會問,你講這麼多到底要怎麼才能知道圖片上的數字是多少.

好吧,說下個人思路,咱們將剛剛的換爲0和1,而這些數字形狀是固定的,這樣就能夠獲得0-9每個字的每個區域8*10都有0和1組成了,
圖片描述

咱們再來進行每8個切分,去掉4格間距,循環得出0-9的01組合值:
圖片描述

$dic = array(
    '00011000001111000110011011000011110000111100001111000011011001100011110000011000' => 0,
    '00011000001110000111100000011000000110000001100000011000000110000001100001111110' => 1,
    '00111100011001101100001100000011000001100000110000011000001100000110000011111111' => 2,
    '01111100110001100000001100000110000111000000011000000011000000111100011001111100' => 3,
    '00000110000011100001111000110110011001101100011011111111000001100000011000000110' => 4,
    '11111110110000001100000011011100111001100000001100000011110000110110011000111100' => 5,
    '00111100011001101100001011000000110111001110011011000011110000110110011000111100' => 6,
    '11111111000000110000001100000110000011000001100000110000011000001100000011000000' => 7,
    '00111100011001101100001101100110001111000110011011000011110000110110011000111100' => 8,
    '00111100011001101100001111000011011001110011101100000011010000110110011000111100' => 9
);

得出這10個後組合成數組,每次解析圖片RGB換成對應數組值就獲得驗證碼值了。下面來演示下:

圖片描述

最後爲了準確性,取100個循環看看:
圖片描述

哈哈,準確率100%

寫在最後

本文的目的是爲了讓WEB開發者在生成驗證碼時注意安全,請勿用於非法目的.

本項目所演示的站點(杭州電子科技大學圖書館->個人圖書館)沒法打開,各位參考原理便可

代碼已在github:https://github.com/chaclee/sf

相關文章
相關標籤/搜索