PHP識(shí)別24位BMP的驗(yàn)證碼_PHP教程
推薦:PHP教程之Ajax進(jìn)行Web開(kāi)發(fā)AJAX無(wú)疑是2005年炒的最熱的Web開(kāi)發(fā)技術(shù)之一,當(dāng)然,這個(gè)功勞離不開(kāi)Google。我只是一個(gè)普通開(kāi)發(fā)者,使用AJAX的地方不是特別多,我就簡(jiǎn)單的把我使用的心得說(shuō)一下。(本文假設(shè)用戶已經(jīng)具有JavaScript、HTML、CSS等基本的Web開(kāi)發(fā)能力) [AJAX介紹] Ajax是使用客戶
PHP識(shí)別24位BMP的驗(yàn)證碼
今天接到個(gè)活,就是識(shí)別一個(gè)簡(jiǎn)單的驗(yàn)證碼,這個(gè)驗(yàn)證碼異常的簡(jiǎn)單,具有很少的干擾信息,所以只要拿到信息進(jìn)行比較.很容易就可以識(shí)別,但是一切不會(huì)那么一帆風(fēng)順的..也許是對(duì)于我來(lái)說(shuō)吧.我覺(jué)得我干什么都十分曲折...
這個(gè)驗(yàn)證碼圖片是用ASP生成的..理所當(dāng)然成了BMP格式.
但是對(duì)于PHP來(lái)說(shuō).這是個(gè)軟傷.因?yàn)镻HP的GD庫(kù)根本就沒(méi)把BMP納入在內(nèi).雖然有wbmp但是還是不一樣的.
所以就google了一下.結(jié)果又讓我一陣喜悅.竟然有個(gè)現(xiàn)成的識(shí)別256色BMP的類..十分激動(dòng)..有這個(gè)還不是白拿錢(qián)的事啊!!
結(jié)果又是令人失望的..256色的BMP跟24位色的根本是兩個(gè)概念..這就意味這我得重新寫(xiě)了..
看來(lái)沒(méi)有現(xiàn)成的類庫(kù)和函數(shù).只能自己寫(xiě)了.用最最原始的fopen.分析BMP頭.一個(gè)一個(gè)字節(jié)的讀了.
所有又去google了BMP的24位色的頭分析..那么長(zhǎng)的文章...立馬就失望了..
所以無(wú)聊就去翻手冊(cè)..眼睜睜的看著有imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromwbmp等等.就是沒(méi)有imagecreatefrombmp
于是突發(fā)奇想.去google一下imagecreatefrombmp會(huì)是什么結(jié)果..果然不出我所料.已經(jīng)有達(dá)人寫(xiě)出了這個(gè)函數(shù)..
這個(gè)函數(shù)的過(guò)程是這樣的..用fopen打開(kāi)文件.一個(gè)字節(jié)一個(gè)字節(jié)的讀出來(lái)..先讀BMP頭.然后逐行讀像素.再用imagecreatetruecolor新建立個(gè)圖像.把剛讀出來(lái)的像素逐個(gè)再畫(huà)到剛才創(chuàng)建的圖片上.
最后返回這個(gè)圖像的resource .
估計(jì)大家跟我一樣.一開(kāi)始就被這么長(zhǎng)的函數(shù)嚇到了.其實(shí)不用怕.分析一下.我們是要分析24位色的BMP.所以上面函數(shù)的大部分語(yǔ)句我們都不用.if($biBitCount==24)以下的才是關(guān)鍵..
$B=freadbyte($f);
$G=freadbyte($f);
$R=freadbyte($f);
這三行就是讀取像素了..我們需要的就是把每個(gè)像素放到數(shù)組中.這樣就容易被操作了.
$array[] = sprintf("d",$R).sprintf("d",$G).sprintf("d",$B);
這樣我們就把每個(gè)像素放到$array這個(gè)數(shù)組中了.但是這樣還不夠.因?yàn)槲覀兊米R(shí)別像素.所以我是這樣想的.把白色的(255255255)改為0.其他顏色改為1.這是因?yàn)槲疫@個(gè)驗(yàn)證碼比較簡(jiǎn)單.而且干擾顏色非常少..
最后形成的$array就類似這樣的了
0001111000 0001111000 0001111000 0000101000
0010000100 0010000100 0010000100 0000100000
0010000100 0010000100 0010000100 0000100000
0010110100 0000000100 0000000100 0000100000
0010110100 0000101000 0000000100 0000100000
0010110100 0000110000 0011000100 0000010000
0010110100 0000001000 0010111000 0000010000
0010000100 0010000100 0010000000 0010001000
0011000100 0010000110 0010000000 0010001000
0001111000 0001111000 0011111100 0011111100
當(dāng)然 之所以形成這個(gè)樣子是我輸出的時(shí)候處理過(guò)的.
很容易看的清楚.這是0357..
有的人會(huì)問(wèn)為什么是倒的?這是因?yàn)锽MP在存儲(chǔ)圖像的時(shí)候就是倒著存放的.比較BT.
不過(guò)這個(gè)不必?fù)?dān)心.我們也不用給他費(fèi)勁正過(guò)來(lái).因?yàn)槲覀兪且霰容^.只要這個(gè)對(duì)比碼也是倒著的就可以了.
為了更清楚的說(shuō)明白這個(gè)數(shù)組是怎么存儲(chǔ)內(nèi)容的.我給大家詳細(xì)的描述一下.就按照上面的例子.
數(shù)組下標(biāo)0 1 2 3 4 5 6 7 8 9 10..... ... 39
存儲(chǔ)內(nèi)容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 0 0 0 1 0 1 0 0 0 第一行
數(shù)組下標(biāo)40 41 .... ...79
存儲(chǔ)內(nèi)容0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 第二行
為了省略我就不寫(xiě)了..很容易看出來(lái).這是個(gè)一維的數(shù)組.一共有399個(gè)元素..但是為了識(shí)別驗(yàn)證碼.我們得把其中的每個(gè)數(shù)字取出來(lái).
0-9 40-49 80-89 ...為一組
10-19 50-59 90-99 ...為一組
20-29 60-69 100-109...為一組
30-39 70-79 110-119..為一組
你可以自己寫(xiě)個(gè)算法..
這樣整理出來(lái)后..是一個(gè)具有4個(gè)元素的數(shù)組.
每個(gè)元素都有100位0和1的數(shù)字.
元素取出來(lái)了.要跟誰(shuí)比較呢??對(duì).我們得找個(gè)參照物才行..
找參照物就是體力活了..
返回到上面的過(guò)程..不斷的刷新驗(yàn)證碼..直到把0-9都出現(xiàn)了.針對(duì)每個(gè).記下他的樣子比如說(shuō)0是這樣
0001111000
0010000100
0010000100
0010110100
0010110100
0010110100
0010110100
0010000100
0011000100
0001111000
變成字符串.0就是這樣了0001111000001000010000100001000010110100001011010000101101000010110100001000010000110001000001111000
也就是上面的按照順序放在一行.
0-9都記下來(lái)后.我們可以放到一個(gè)數(shù)組中,就叫$key吧.
這樣的話跟我們生成出來(lái)的元素就一一對(duì)應(yīng)了.
下面就要開(kāi)始比較了.
循環(huán)是免不了的.比較的技巧是用similar_text和參照物逐個(gè)比較.把相思百分比放到一個(gè)數(shù)組中.
然后把這個(gè)數(shù)組中最大的那個(gè)百分比取出來(lái).所對(duì)應(yīng)的索引值(此索引值不是自動(dòng)生成的)就是我們識(shí)別出來(lái)的數(shù)字了.
下面的代碼值描述重要的部分
然后取出$maxArr這個(gè)最大的索引值.就是我們識(shí)別出來(lái)的數(shù)字了.
到此驗(yàn)證碼算是識(shí)別完成了.
但是部署給用戶的時(shí)候.發(fā)現(xiàn)他的機(jī)器上用fopen打開(kāi)遠(yuǎn)程URL.只有30%的幾率能獲取到.其他的情況都是HTTP Request failed...
更改了很多方法還是不成功.結(jié)果我的解決辦法是.
用CURL把驗(yàn)證碼保存到本地.然后fopen打開(kāi)本地圖片就100%OK啦..
分享:淺談PHP數(shù)組讀取的循環(huán)操作PHP基本上就是一種數(shù)組語(yǔ)言。時(shí)常要進(jìn)行大量的數(shù)組循環(huán)操作,主要有兩種方式,一種是foreach,另一種是while,到底哪種好哪種壞一直有爭(zhēng)論,雖然我很早就意識(shí)到了這個(gè)問(wèn)題,但是一直沒(méi)有細(xì)究,懵懂的感覺(jué)一直持續(xù)到現(xiàn)在,為了以后能節(jié)省點(diǎn)CPU時(shí)間,下面總結(jié)
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁(yè)面代碼執(zhí)行時(shí)間
- PHP中獎(jiǎng)概率的抽獎(jiǎng)算法程序代碼
- apache設(shè)置靜態(tài)文件緩存方法介紹
- php對(duì)圖像的各種處理函數(shù)代碼小結(jié)
- PHP 關(guān)于訪問(wèn)控制的和運(yùn)算符優(yōu)先級(jí)介紹
- 關(guān)于PHP語(yǔ)言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國(guó)語(yǔ)言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
PHP教程Rss訂閱編程教程搜索
PHP教程推薦
- PHP與正則表達(dá)系列之一: PHP中的正則表達(dá)式
- Web開(kāi)發(fā)源代碼:PHP生成靜態(tài)頁(yè)面的類
- php正則表達(dá)式使用的詳細(xì)介紹
- 十天學(xué)會(huì)php之第十天
- php面向?qū)ο髉ublic private protected 訪問(wèn)修飾符
- 解析PHP技術(shù):txtSQL安裝手冊(cè)中文版
- PHPMailer郵件發(fā)送的實(shí)現(xiàn)代碼
- 基于php驗(yàn)證碼函數(shù)的使用示例
- 怎樣使用PHP服務(wù)端代理抓取網(wǎng)頁(yè)內(nèi)容
- 解決PHP無(wú)法訪問(wèn)遠(yuǎn)程mysql的問(wèn)題
- 相關(guān)鏈接:
- 教程說(shuō)明:
PHP教程-PHP識(shí)別24位BMP的驗(yàn)證碼。