首頁  >  文章  >  web前端  >  利用html5 canvas破解簡單驗證碼及getImageData介面應用_html5教學技巧

利用html5 canvas破解簡單驗證碼及getImageData介面應用_html5教學技巧

WBOY
WBOY原創
2016-05-16 15:50:101528瀏覽

敝校的教務管理系統(看似不止我們學校用呢),一到選課時間服務器各種崩不解釋,有時為了選個課就要反復輸入驗證碼,一想到千千萬萬的大學生把時間浪費在輸入驗證碼上面,我就覺得,我有義務去拯救人類。

搜了一下,看到這篇文章,3年前的文章了。我參考了前半部分,借助TamperMonkey這個插件,大概達到了想要的效果。可以在Userscript取得這個腳本,GitHub上面也有,程式碼寫得醜,求debug,求指教。
說下想法:HTML 5中的canvas有個介面getImageData可以用來從驗證碼影像中取得像素資料。每一個像素有對應r,g,b,a四個值,r,g,b是紅綠藍三色,a是透明度。

觀察到教務管理系統的驗證碼是5個數字,字體字號大小都不變,而且雖然背景雖然有乾擾,但是很明顯跟字體顏色有很大區別,所以就用了一個很粗糙的方法:我們知道,顏色越淺,rgb值越大,顏色越深,rgb值越少。於是我對每一個像素點進行判斷,rgb的和小於350(這個值是測出來的)的就是屬於字體的像素,為了方便觀察,把它的rgb值都設定為255,否則設定為0。這樣就獲得了一個黑底白字的圖片了。

複製程式碼
程式碼如下:

var ctx = canvasd ');
ctx.drawImage(img,0,0);
var c = ctx.getImageData(0,0,img.width,img.height);
for(i=0; i for(j=0; jvar x = (i*4)*c.width (j*4);
var r = c.data[x];
var g = c.data[x 1];
var b = c.data[x 2];
if(r g b > 350){
c.data[x] = c.data[x 1] = c.data[x 2] = 0;
}
else{
c.data[x] = c.data[x 1] = c.data[x 2] = 255;
}
}
}  

然後我用畫圖工具放大圖片,觀察了一下,得到每個圖片數字是一個12*8像素的矩形,再之後就求出每一個數字對應的像素個數,發現0和8還有6和9的像素個數是一樣的,就進行一下特判(比如正中間有像素的就一定是8而不是0了)。然後…還是觀察一下…每個數字對應的矩陣的座標…寫出這個函數:

複製程式碼
程式碼如下:

function getNum(imgData,x1,y1,x2,y2){
var num = 0;
for(i=y1; ifor(j=x1; jvar x = (i*4)*imgData.width (j*4);
if(imgData.data[x] == 255)num ;
}
}
switch(num)
{
case 56:{
j = (x1 x2)/2;
i = ( y1 y2)/2;
var x = (i*4)*imgData.width (j*4);
if(imgData.data[x] == 255)
return 8;
else
return 0;
}
case 30:return 1;
case 50:return 2;
case 51:return 3;
case 48:return 4
case 57:return 5;
case 58:{
i = y2-2;
j = x1;
var x = (i*4)*imgData.width (j*4) ;
if(imgData.data[x] == 255)
return 9;
else
return 6;
}
case 37:return 7;
default: return 0;
}
}

原文用了神經網路來判斷,準確率大大提高,我不會用,所以就沒用了…
我用這個方法獲得的驗證碼準確率也有95%以上,暫時夠用了。有空再研究一下神經網路好了。
有需要的同學可以拿去用,Chrome瀏覽器要先裝TamperMonkey,Firefox則是GeaseMonkey,然後安裝這個腳本就ok了。
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn