C#下的驗證碼識別

引言

1)驗證碼的基本知識及來由
網絡安全技術中的驗證碼的主要目的是強制人機交互來抵禦機器自動化攻擊。用來防止機器模擬http行爲,直接抓取文本進行導航;或直接提交文本進行登錄嘗試。在現在帶寬較大的今天,在線密碼窮舉帶寬已經不能作爲瓶頸了,驗證碼識別以2M ADSL連接實際測試,20線程大概每秒可以完成30個左右的連接,如果是6位數字密碼,在不考慮字典完全窮舉的時候也只需要幾個小時便可破解,嚴重的威脅了網絡賬號的安全,因此,網絡登錄註冊驗證碼的普及勢在必行。
而如今國內大部分的驗證碼設計者並不得要領,要麼不瞭解圖像處理、機器視覺、模式識別、人工智能的基本概念;要麼設計出的驗證碼連人都難以識別,導致用戶體驗度下降。 比如工商銀行的WAP手機銀行驗證碼,只有4位,而且驗證碼的薄弱形同虛設,使用窮舉計算機很快就能破解一個六位數字密碼的賬戶。當然,也有設計得比較好的,比如Yahoo、Google、baidu等。
2)驗證碼的展望
未來的網絡安全驗證碼,可能更多地使用漸進色層、同級灰度色差,更多曲線反轉、隨機字符數量、字符粘連等手段防止機器的識別,但加密與破解總是一對孿生兄弟,不可能消失一方的。我們只是希望通過本文,給編寫驗證碼算法的人員一些建議,使我們的網絡更安全,操作也不會因此而繁瑣。

算法分析

在驗證碼處理方面,我們大概要涉及到如下內容:人工智能、模式識別、機器視覺、圖像處理。
1) 主要流程:如果我們要從一幅圖片中識別出驗證碼;又或者我們要從一幅圖片中檢測並識別出一個字符,其步驟可概括如下:
圖像採集:取得一個驗證碼,就直接通過HTTP抓HTML,然後分析出圖片的URL,下載保存。
預處理:檢測是正確的圖像格式,轉換到合適的格式,壓縮,剪切出ROI,去除噪音,灰度化,轉換色彩空間。
檢測:找出文字所在的主要區域。
前處理:文字的切割、縮放和扭曲校正。
訓練:通過各種模式識別,機器學習算法,來挑選和訓練合適數量的訓練集。訓練的樣本並非越多越好。通過學習,泛化能力差的問題可能會出現在這裏。
識別:輸入待識別的處理後的圖片,轉換成分類器需要的輸入格式,通過輸出的類和置信度,來判斷大概可能是哪個字母。識別本質上就是分類。
2)關鍵概念
圖像處理:一般指針對數字圖像的某種數學處理,比如投影、鈍化、銳化、細化、邊緣檢測、二值化、壓縮,以及各種數據變換等等。
二值化:一般圖片都是彩色的,按照逼真程度,可能很多級別。爲了降低計算複雜度,方便後續的處理,如果在不損失關鍵信息的情況下,能將圖片處理成黑白兩種顏色,那就最好不過了。
細化:找出圖像的骨架,圖像線條可能是很寬的,通過細化將寬度降爲1,某些地方可能大於1。不同的細化算法,可能有不同的差異,比如是否更靠近線條中間,比如是否保持聯通行等。
邊緣檢測:主要是理解邊緣的概念。邊緣實際上是圖像中圖像像素屬性變化劇烈的地方,可以通過一個固定的門限值來判斷,也可以是自適應的。門限可以是圖像全局的,也可以是局部的。不能說哪個就一定好,不過大部分時候,自適應的局部的門限可能要好點。被分析的可能是顏色,也可能是灰度圖像的灰度。
機器視覺:利用計算機來模式實現人的視覺,比如物體檢測、定位、識別。按照對圖像理解的層次的差別,分高階和低階的理解。
模式識別:對事物或者現象的某種表示方式(數值、文字,我們這裏主要想說的是數值),通過一些處理和分析來描述、歸類、理解、解釋這些事物、現象及其某種抽象。
人工智能:這種概念比較寬,上面這些都屬於人工智能這個大的方向。簡單點不要過分學院派的理解就是,把人類的很“智能”的東西給模擬出來,協助生物的人來處理問題,特別是在計算機裏面。

驗證碼識別原理及代碼演示

本來拿一個銀行網站來進行驗證碼解密是很危險的,但我們發現,工行的算法已經進行了改變,所以姑且以之前的工行WAP銀行做個舉例好了,同時也希望工行的加密能越做越好。
其實工行的WAP驗證碼是很簡單的,是未加干擾的原始字符打印圖片而已。針對這種驗證碼,我們將使用點陣庫校驗的方式進行,首先從整個程序的編寫及操作順序開始。
首先要知道我們需要取得的字的點陣有哪些。工行的WAP銀行驗證碼只有0~9,10個數字,那麼我們先將驗證碼圖片下載到本機,這裏我們必須將所有字符的圖樣都下載到本機,以便建立基礎點陣庫。
得到這些圖片文件後,我們將用程序來獲得圖片點陣。從本地磁盤加載一個圖像文件,這個文件是我們已經下載好的。首先應該讓程序先將0~9的圖像都“識別”一遍,使我們的程序“記住”它們的點陣,樣例如圖1所示。該圖像包含的驗證碼,從左到右就是0123,將這個圖像逐點轉換灰度,也就是將彩色圖片先進行灰度化、去色,變成黑白照片,便於下一步操作。

灰度化之後,像素的RGB三色都是相同的值了,亮度從0~255(HxFF)。但用於識別程序,灰度值並不能很好的區分背景色和前景色,尤其是對於漸進的背景來說,所以我們還要將圖像進一步處理,就是將灰度圖片2值化,類似的算法還有分水嶺算法等。因爲本文中的驗證碼相對簡單,故直接使用2值化轉換,尋找有效區並轉爲單色黑白圖。

圖2

在平均分割圖片的部分,設置水平上分割數爲RowNum,垂直上分割數爲ColNum,返回分割好的圖片數組,程序編寫如下:


此時圖像分割已結束,pics 的長度應該是4,並且每一個pics就是一個驗證碼的位圖,經過錯誤處理,修邊,和去除無用背景空白,修正完的位圖爲數字0。
得到有效圖形後,由外面傳入該圖形,設置灰度背景分界值爲“dgGrayValue”,有效字符數爲CharsCount,程序編寫如下:


至此,pics圖像組中就是有效的點陣圖了。下面我們把pics中的圖形轉換爲代表點陣的字符串,返回灰度圖片的點陣描述字串,1表示灰點,0表示背景。設置灰度圖爲singlepic,背前景灰色界限爲dgGrayValue。

此時,code中的字符串就代表字符0在工行WAP銀行上圖像驗證碼的值了;以此類推,我們可以得到一個完整的,代表圖像0~9的數組,字符表的順序爲0~9,A~Z,a~z。
現在,圖片點陣數組已經取得了,接下來我們看看如何把一個圖片識別出來吧!已知如下的點陣表:

開始處理比較操作:

至此,sbResult中的4個數字就是圖像上的4個數字了。
結論
驗證碼識別肯定不只是這麼簡單,但現在還是有很多網站都在用這種未經任何變換的驗證碼,所以我們的網絡安全還任重而道遠。
上面的驗證碼識別是一個最基本的算法,但是很多擴展算法都可以基於上面的思路進行擴充。例如有些驗證碼進行了旋轉輸出,那麼上面的程序可以在校對的時候,進行360度旋轉,旋轉後的圖像再取得序列,再和圖像序列比較,直至得到最符合的。有些驗證碼添加了邊框,此時我們可以先去掉邊框再進行切割匹配。
通過上面的算法可以得出,我們今後在設計驗證碼的時候,應該注意如下因素:
1)在噪音等類型的使用上,盡力讓字符和用來混淆的前景和背景不容易區分,盡力讓噪音長得和字母一樣。
2)特別好的驗證碼的設計,要盡力發揮人類擅長而AI算法不擅長的。比如粘連字符的分割和手寫體(通過印刷體做特別的變形也可以),而不要一味的去加一些看起來比較複雜的噪音或者其他的花哨東西。
3)從專業的機器視覺的角度來說,網絡安全驗證碼的設計,一定要讓破解者在識別階段,反覆在低階視覺和高階視覺之間多反覆幾次才能識別出來,這樣可以大大降低破解難度和破解的準確率。

發佈了47 篇原創文章 · 獲贊 9 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章