天天看點

驗證碼應用

  驗證碼應用目的:

  為了防止某些别有用心的使用者利用機器人(惡意程式)自動注冊、自動登入、惡意灌水、惡意增加資料庫通路、用特定

驗證碼應用

程式暴力破解密碼,可采用驗證碼技術。

  另外一個好處是,使得你的網站給人一種很酷的感覺。

  

  驗證碼應用原理:

  浏覽器應用HTML标準與網站伺服器動态聯系,在HTML的表單中,基本上都是使用指定有Action的POST方法。如果不應用驗證碼方法,将很容易被一些别有用心的人利用機器人程式或者盜用Action的惡意程式,實作其個人勾當。應用驗證碼技術後,可以保護你的伺服器,防止這一問題的發生。

  應用驗證碼技術後,表單上将多出一個驗證碼文本框輸入項目,并且表單上的某個位置還顯示有一個圖檔,這個圖檔是由一些可由人工識讀的數字和字元組成的。這是應用驗證碼技術後的前台特征。背景特征是,伺服器在生成驗證碼圖檔的時候,以Session或者其它方式在伺服器端儲存驗證碼的明文字元串。

  使用者在輸入表單内容的時候,還要求使用者識讀表單上的這個的驗證碼圖檔并将識讀結果輸入到驗證碼文本框内。當伺服器收到這樣的表單後,首先将使用者送出的驗證碼與Session值進行比較,根據比較結果判斷使用者是否為合法使用網站功能。

  

  驗證碼應用注意事項:

  為了防止電腦OCR讀圖程式識别和破解驗證碼,一般需要在合理範圍内适當增加對驗證碼圖檔的識别難度。處理手段主要是對色彩、形狀、幹擾元素、位置進行變異處理,使得生成的驗證碼圖檔不具有程式閱讀的規律性。目前常用方法有:數字和字母混合、随機産生字元個數、随機扭曲翻轉字元、随機增加背景噪點、随機添加幹擾條紋、随機變化字元在圖檔上的位置、随機變化背景顔色和字元顔色、随機變化字元大小、随機變化字元間距,等等。在增加識别難度上需要掌握好度。如果使用者太難識别驗證碼了,會影響使用者對網站的使用積極性。

  網站應用驗證碼後,将增大伺服器壓力,具體表現在兩個方面。一是因為生成驗證碼時使用了許多的算法,生成驗證碼過程中會占用伺服器CPU時間,二是應用Session會消耗伺服器記憶體。是以,并不是在網站中到處都用。目前主要是在重要表單送出時使用。

  伺服器生成的驗證碼明文不能儲存在用戶端浏覽器上,否則被使用者讀取後就失去了驗證的作用。

  驗證碼技術,對傳統的HTML标準的表單是具有顯著防護作用的。在ASP.NET和其它技術飛速發展的今天,可以通過許多其他的方法達到同樣的目的。如ASP.NET就應用了全新的Form技術,摒棄了Form的Action,對表單上的按鈕Handles事件,通過該事件的伺服器程式處理表單動作。再譬如。分步驟送出表單也可達到保護目的。是以說,驗證碼技術将很快退出曆史舞台。

  

  驗證碼式樣:

  本文示例程式可提供的式樣及可實作的功能:

  标準式樣:

驗證碼應用
  背景顔色随機變化:
驗證碼應用
  幹擾線條随機變化:
驗證碼應用
  幹擾噪點随機變化:
驗證碼應用
  扭曲程度随機變化:
驗證碼應用
  首字元位置随機變化:
驗證碼應用
  随機增加3D陰影:
驗證碼應用
  字元數量随機變化:
驗證碼應用
  字型大小随機變化:
驗證碼應用

  

  Yahoo驗證碼式樣:

  

驗證碼應用

  

  CSDN驗證碼式樣:

  

驗證碼應用

  

  Sina驗證碼式樣:

  

驗證碼應用

  

  鳳凰網驗證碼式樣:

  

驗證碼應用

  

  驗證碼生成方法:

  1、随機産生一定長度的字元;

  2、使用System.Drawing命名空間的Graphics類的方法将字元繪制成圖檔;

  3、在第二步的基礎上,使用各種方法對圖檔進行各種操作,使之複雜化,增加識别難度。

  

  驗證碼應用前台程式:

  

以下是代碼片段:

  <body>

    <form id="form1" runat="server">

    <div>

    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

    <asp:Image ID="Image1" runat="server" ImageUrl="VerifyChar.aspx" /><br />

    <br />

    <asp:Button ID="Button1" runat="server" Text="送出" /></div>

    </form>

  </body>

程式的核心是,将圖檔引用的URL指向驗證碼圖檔生成程式。

  

  驗證碼圖檔生成程式:

  以下程式在VS2003和VS2005下通過。

  

以下是代碼片段:

  

  Imports System.IO

  Imports System.Drawing

  Imports System.Drawing.Imaging

  Imports System.Drawing.Drawing2D

  Partial Class VerifyChar

    Inherits System.Web.UI.Page

    Private Const PI As Double = 3.14159265358979

    Private Const PI2 As Double = 6.28318530717959

  

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache) ’不緩存

    Dim x, y, x1, y1 As Single

    Dim PenWidth1, PenWidth2, VerifyVharFont As Integer

    Dim VerifyChar As String = RndChar(4) ’RndChar是一個自定義函數

    Dim Img As System.Drawing.Bitmap

    Dim g As Graphics

    Dim backBrush As Brush = Brushes.DimGray

    Dim textBrush As Brush = Brushes.Black

    VerifyVharFont = Int(7 * Rnd()) + 14  ’驗證碼字元字型大小随機生成

    Dim textFont As New Font("Arial", VerifyVharFont, FontStyle.Strikeout)  ’驗證碼字型

    Dim ms As MemoryStream

    Dim gWidth As Integer = Int(Len(VerifyChar)) * VerifyVharFont + VerifyVharFont  ’驗證區寬度。如果字元都為W,不加寬是不行的

    Img = New Bitmap(gWidth, 30)  ’驗證區高度

    ’生成随機背景顔色

    Dim nRed, nGreen, nBlue As Integer ’ 背景的三元色

    Dim rd = New Random  ’(CInt(System.DateTime.Now.Ticks))

    nRed = rd.Next(255) Mod 128 + 128

    nGreen = rd.Next(255) Mod 128 + 128

    nBlue = rd.Next(255) Mod 128 + 128

    ’在圖檔框picCanvas上面建立一個新的空白Graphics

    g = Graphics.FromImage(Img)

    ’填充位圖背景

    g.FillRectangle(New SolidBrush(System.Drawing.Color.FromArgb(nRed, nGreen, nBlue)), 0, 0, Img.Width, Img.Height)

    ’随機輸出噪音線

    Dim i As Int32

    For i = 0 To 2

    Randomize()

    x = Img.Width * Rnd()

    y = Img.Height * Rnd()

    x1 = Img.Width * Rnd()

    y1 = Img.Height * Rnd()

    PenWidth1 = 2 * Rnd() ’修改參數可獲得不同的效果

    g.DrawLine(New Pen(backBrush, PenWidth1), x, y, x1, y1)

    Next

    ’随機輸出噪點

    PenWidth2 = 2 ’修改參數可獲得不同的效果

    For i = 0 To 10

    Randomize()

    x = Img.Width * Rnd()

    y = Img.Height * Rnd()

    nRed = rd.Next(255) Mod 128 + 128

    nGreen = rd.Next(255) Mod 128 + 128

    nBlue = rd.Next(255) Mod 128 + 128

    g.DrawRectangle(New Pen(Color.FromArgb(nRed, nGreen, nBlue), PenWidth2), x, y, 1, 1)

    Next

    ’文字的位置

    x = 16 * Rnd() - 6 ’随機産生X軸位置,增加程式識别難度

    y = 0

    ’随機畫3D背景

    Dim S3d As Single = Rnd()

    If S3d > 0.9 Then

    For i = 1 To 0 Step -1

    g.DrawString(VerifyChar, textFont, backBrush, x - i, y + i)

    Next

    End If

    ’将全局變換平移(x, y),也就是使畫布上将要畫的所有内容向左邊移動x,向下移動y

    g.TranslateTransform(1.5, 1)

    ’做切變,将原始矩形的下邊緣水準移動矩形高度的0.2倍

    Dim textTransform As Matrix = g.Transform

    textTransform.Shear(0.2, 0)

    g.Transform = textTransform

    ’畫出文字

    g.DrawString(VerifyChar, textFont, textBrush, x, y)

    Me.Session("VerifyChar") = VerifyChar ’将驗證字元寫入Session,供前台調用

    ’扭曲驗證字元。TwistImage參數可自行修改

    Dim Twist1, Twist2 As Single

    If S3d > 0.9 Then  ’3D背景減少扭曲

    Twist1 = 0

    Twist2 = 0

    Else

    Twist1 = Rnd() * 3  ’扭曲參數随機生成

    Twist2 = Rnd() * 2  ’扭曲參數随機生成

    End If

    Img = TwistImage(Img, True, -Twist1, -Twist2)

    Img = TwistImage(Img, False, Twist1, Twist2) ’多扭曲幾次也沒關系,隻是消耗伺服器資源多些

    ms = New MemoryStream

    Img.Save(ms, ImageFormat.Png)

    Response.ClearContent() ’需要輸出圖象資訊 要修改HTTP頭

    Response.ContentType = "image/Png"

    Response.BinaryWrite(ms.ToArray())

    g.Dispose()

    Img.Dispose()

    Response.End()

    End Sub

  

    ’函數名稱:RndChar

    ’函數參數:VcodeNum--設定傳回随機字元串的位數

    ’函數功能:産生指定長度的由數字和字元組成的随機字元串

    Function RndChar(ByVal VcodeNum) As String

    Dim Vchar As String = "3,3,5,5,6,6,7,7,9,9,A,C,E,F,G,H,K,L,M,N,P,R,T,X,Y,Z" ’定義驗證碼字元及出現頻次

    Dim VcArray() As String = Split(Vchar, ",") ’将字元串生成數組

    Vchar = ""

    Dim i As Byte

    For i = 0 To Int(VcodeNum * Rnd()) + 1  ’確定最少2個字元,最多VcodeNum+1個字元

    Randomize()

    Vchar = Vchar & VcArray(Int(25 * Rnd())) ’數組一般從0開始讀取,是以這裡為25*Rnd

    Next

    Return Vchar

    End Function

  

    ’函數名稱:TwistImage

    ’函數參數: dMultValue-波形的幅度倍數;dPhase波形的起始相位,取值區間[0-2*PI);bXDir-扭曲方式

    ’函數功能:正弦曲線Wave扭曲圖檔。函數可以疊加使用,以獲得不同方式不同程度的效果

    ’這個天才的函數,已經無法考證出處了。感謝原作者!

    Public Function TwistImage(ByVal srcBmp As Bitmap, ByVal bXDir As Boolean, ByVal dMultValue As Double, ByVal dPhase As Double) As Bitmap

    Dim destBmp = New Bitmap(srcBmp.Width, srcBmp.Height)

    Dim dBaseAxisLen As Double = IIf(bXDir, CDbl(destBmp.Height), CDbl(destBmp.Width)) ’ToDo: Unsupported feature: conditional (?) operator.

    Dim i As Integer

    For i = 0 To destBmp.Width - 1

    Dim j As Integer

    For j = 0 To destBmp.Height - 1

    Dim dx As Double = 0

    dx = IIf(bXDir, PI2 * CDbl(j) / dBaseAxisLen, PI2 * CDbl(i) / dBaseAxisLen) ’ToDo: Unsupported feature: conditional (?) operator.

    dx += dPhase

    Dim dy As Double = Math.Sin(dx)

    ’ 取得目前點的顔色

    Dim nOldX As Integer = 0

    Dim nOldY As Integer = 0

    nOldX = IIf(bXDir, i + CInt(dy * dMultValue), i) ’ToDo: Unsupported feature: conditional (?) operator.

    nOldY = IIf(bXDir, j, j + CInt(dy * dMultValue)) ’ToDo: Unsupported feature: conditional (?) operator.

    Dim color As System.Drawing.Color = srcBmp.GetPixel(i, j)

    If nOldX >= 0 And nOldX < destBmp.Width And nOldY >= 0 And nOldY < destBmp.Height Then

    destBmp.SetPixel(nOldX, nOldY, color)

    End If

    Next j

    Next i

    Return destBmp

    End Function

  End Class

繼續閱讀