關於ASP.NET中圖片驗證碼使用的掃盲


  先說說什么是驗證碼吧,它是一種區分用戶是計算機和人的公共全自動程序。可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定注冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試,實際上是用驗證碼是現在很多網站通行的方式(比如招商銀行的網上個人銀行,百度社區),我們利用比較簡易的方式實現了這個功能。圖片驗證碼嘛!嘿嘿,就是用圖片的形式表述出來這個驗證碼嘍!至於為什么用圖片的形式表示下面說。

      不知道大家有木有發現,有的時候上論壇,經常看見什么賣假煙啦,賣茶葉的,一發就是好幾頁的廣告~這也就是沒有驗證碼的原因。其實那些發布廣告貼的用戶也不是人手工發貼的,想想啊,那還不累死,為了5毛,不值得啊!都是利用一個發帖的小程序,批量發帖的,如果這個時候我們的ASP.NET網站使用了圖片驗證碼技術的話,簡單的發帖程序就沒有辦法幫主人工作了,整個世界都清凈了,有木有?

      還有就是多年前很流行(現在也很流行,但是應用的地方不一樣了)傳說中的暴力破解,所謂暴力破解,也就是沒有什么技術含量,用一個暴力破解的程序,一直變化密碼來試驗,直到把這個密碼試驗出來,這個方法在理論上來說還是很牛b的,無論什么樣的密碼,都可因由暴力破解破解出來。不過話說回來,理論只是理論,但是破解的時間呢?可以想象,密碼越長,試驗的時間就越長。后來干壞事的人覺得,這破解的時間也太長了,等不及,就把大家經常用的密碼形成一個字庫,比如生日格式的,電話號碼格式的等等,這樣就大大的增加了破解的成功率以及破解所花的時間,有些人設置的密碼還偏偏就是這樣的弱類型密碼,唉。。。。明知山有虎偏向虎上行啊~

      好了好了,話題都扯遠了,今天我就簡單的介紹一下傳說中ASP.NET中的圖片驗證碼技術。

      其實也不是很難,原理就是這樣的,在用戶提交信息到服務器之前做一個驗證,就是我們動態生成的圖片驗證碼,輸入正確,就可以向服務器提交。有人就說了,我們這里為什么要用一張圖片?用一串動態生成的字符密碼豈不是更好,節省網絡資源,提高網站的性能?哈哈~這里就是人和程序的不一樣之處了,人能讀懂各種資源,圖片上的文字也不例外,如果只是網頁中簡單的一點字符,雖然人能明白是什么,但是程序也可以讀出來啊!這樣自動發帖或者暴力破解程序一樣可以識別簡單的字符啊!就違背了我們的初衷,所以這里使用的一定是圖片驗證碼,這樣程序要是想識別就難嘍~

好了,現在看看具體實現的過程,這里只是一個簡單的例子,如果應用在網站中需要考慮的就不只是這么簡單了,這里只是圖片驗證碼技術的一個原理哦~

第一看看我們需要用到的東西。

       第一個就是C#中的Random類,它是表示偽隨機數生成器,一種能夠產生滿足某些隨機性統計要求的數字序列的。說白了,既然是驗證碼,就要有一個隨機動態產生的一串字符,用它作為驗證碼,C#中的Random類就是我們用來生成驗證碼的類。我們這里只要使用它的Next()方法,這個方法會返回一個隨機的正整數。

   第二個就是Session,它提供對會話狀態值以及會話級別設置和生存期管理方法的訪問。Session 是 用於保持狀態的基於 Web 服務器的方法。Session 允許通過將對象存儲在 Web 服務器的內存中在整個用戶會話過程中保持任何對象。Session 的作用就是它在 Web 服務器上保持用戶的狀態信息供在任何時間從任何頁訪問。因為瀏覽器不需要存儲任何這種信息,所以可以使用任何瀏覽器,即使是像 PDA 或手機這樣的瀏覽器設備。所以這里,我們就把用Random生成的驗證碼存儲在Session中,方便我們使用。

       第三就是C#中的Bitmap類,它封裝 GDI+ 位圖,此位圖由圖形圖像及其特性的像素數據組成。 Bitmap 是用於處理由像素數據定義的圖像的對象。說白了就是用它創建一張圖片,並且做出一些修改。

       第四個就是Graphics類,它封裝一個GDI+繪圖圖面,我們主要用它的DrawString()方法,在圖片上寫上我們的驗證碼。

       好了,用到的東西不多,就這四個,我們開始Coding吧!

       第一步,實例化一個stirng類型的變量備用,一會兒我們把我們生成的驗證碼存在里面。這個,就不做過多介紹了。

1 string str;

 

       第二步,用Random.next(0,100)得到三個0-100之間的隨機數,把他們拼到一起,存在第一步實例化好的string變量中,這就是什么的驗證碼了,老鳥可能說了,這個驗證碼是不是太簡單了?當然是的!這里說的就是一個原理,以后應用中我們可以利用Random出來的整數生成很多字符,比如把得到的隨機數用ASCII碼的方式轉換成大、小寫的字符,甚至符號都可以,這里為了方便說明,所以就只用3個隨機獲得的整數作為驗證碼吧。

  這里介紹一下rand.next(x,y)這個方法就是說返回一個正整數,它大於x並且小於y。

1 Random rand = new Random();
2 int v1 = rand.Next(0, 100);
3 int v2 = rand.Next(0, 100);
4 int v3 = rand.Next(0, 100);
5 str = v1.ToString() + v2.ToString() + v3.ToString();

 

       第三步,把生成好的string驗證碼放在Session中備用。

1 Context.Session["Code"] = str;

 

       第四步,實例化一個Bitmap類,作為我們的畫板,這里我用了一張空白的圖片,方便一會兒在上面寫寫畫畫~

  這里實例化Bitmap的時候我們的參數是一張圖片的地址,意識是從指定的現有圖像初始化 Bitmap 類的新實例。

1 Bitmap bitmap = new Bitmap(Context.Server.MapPath("~/Image/1.jpg"));

 

       第五步,實例化一個Graphics類,備用作為一個畫筆,在一會兒畫圖片的時候用。

  這里可以看出,實例化Graphics類的時候我們用到的方法是FromImage(),顧名思義,從指定的現有圖像初始化 Bitmap 類的新實例。

1  Graphics g = Graphics.FromImage(bitmap);

 

       第六步,把Random到的驗證碼用DrawString方法畫在剛剛實例化的Bitmap上。

  這里用到的DrawString()意思方法是在指定位置並且用指定的 Brush 和 Font 對象繪制指定的文本字符串。具體參數是這樣DrawString(字符串,字體,顏色,橫豎坐標)。

1 g.DrawString(str, new Font("黑體", 15), Brushes.Red, 0, 0);

 

       第七步,用Bitmap類的SetPixe方法在畫好驗證碼的圖片上畫一些點點,這樣只有人才能看懂了吧?當然,顏色的選擇這里也是Random得到的。

  這里還是用到了rand.Next,不過這次的參數只有一個rand.Next(x),意思是返回一個值不大於x的正整數,可以想象,如果大於圖片也就是我們的畫布的大小,我們往哪里畫呢?還有就是bitmap.SetPixel()上面已經說過,這個方法是在畫布上畫小點點,它本身是不會“畫”東西的,只是改變了給定位置像素的顏色,也就達到了我們的目的,具體的參數是這樣的SetPixel(x坐標,y坐標,顏色),這里的顏色也是用rand隨機得到的一個顏色,FromArgb方法故名思議就是指定 32 位 ARGB 值的值。我在這里畫了300個。

1 for (int i = 0; i < 300; i++)
2 {
3      int x = rand.Next(bitmap.Width);
4      int y = rand.Next(bitmap.Height);
5      bitmap.SetPixel(x,y,Color.FromArgb(rand.Next()));
6 }

 

       最后一步,我們保存生成好的圖片驗證碼吧!

1 bitmap.Save(Context.Server.MapPath("~/Image/2.jpg"));

  來吧,看看完整的方法:

 1 public void createImage()
 2         {
 3             string str;
 4             Random rand = new Random();
 5             int v1 = rand.Next(0, 100);
 6             int v2 = rand.Next(0, 100);
 7             int v3 = rand.Next(0, 100);
 8             str = v1.ToString() + v2.ToString() + v3.ToString();
 9             Context.Session["Code"] = str;
10             Bitmap bitmap = new Bitmap(Context.Server.MapPath("~/Image/1.jpg"));
11             Graphics g = Graphics.FromImage(bitmap);
12             g.DrawString(str, new Font("黑體", 15), Brushes.Red, 0, 0);
13             for (int i = 0; i < 300; i++)
14             {
15                 int x = rand.Next(bitmap.Width);
16                 int y = rand.Next(bitmap.Height);
17                 bitmap.SetPixel(x,y,Color.FromArgb(rand.Next()));
18             }
19             bitmap.Save(Context.Server.MapPath("~/Image/2.jpg"));
20         }

 

  嘿嘿,看看其實很簡單就完成了,最后看看效果:

  還不錯吧~這就是傳說中的驗證碼啦~對了,今天2012-10-24,是傳說中的程序員節哦~祝所有的程序員節日快樂哦~也幾年我在博客園的第一篇隨筆~就到這里了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM