65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 中的 CAPTCHA 图形

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (19投票s)

2009 年 10 月 30 日

CPOL

1分钟阅读

viewsIcon

71371

downloadIcon

5646

生成 CAPTCHA 图形,可用于网站以帮助验证用户。

引言

什么是 CAPTCHA?

CAPTCHA 是 Completely Automated Public Turing test to tell Computers and Humans Apart(完全自动图灵测试以区分计算机和人类)的缩写。

该方法使用单词或数字的图像,理论上这些图像经过扭曲和混淆,使得光学字符识别程序无法读取,但人类应该能够轻松读取。

Failed.JPG

Help.JPG

Success.JPG

背景

这个类是一个简单的类,它构建

  1. 六个字符(使用数字 0-9、大写字母 A-Z 和小写字母 a-z)。
  2. 区分大小写。
  3. 具有动态字体颜色和位置。
  4. 提供帮助(可以在消息框中清晰看到)。

使用构造函数

使用 Captcha 类创建一个 CAPTCHA 图像。它有两个构造函数,一个带参数(由用户定义),一个不带参数(由系统设置)。

以下示例描述了如何使用带参数或不带参数的构造函数创建 captcha 图像

Private Sub DisplayCaptcha()
    'Save the generated CAPTCHA on phisical drive 
    'with the name of "CAPTCHA.jpg"
    'if you want to save with different name ("mycaptcha.jpg") 
    'instead of "CAPTCHA.jpg" 
    Dim strFile As String = "CAPTCHA.jpg"

    'There are two methods of CAPTCHA
    '1. Without argument (Default width:180, height:40,
    '                     fontstyle: [Name:Georgia,Size:30,Style:Bold])
    'Dim captcha = New Captcha() 

    '2. With argument (CAPTCHA width,CAPTCHA height,CAPTCHA font style)
    'Dim captcha = New Captcha(180, 55, fnt)

    'Set CAPTCHA font style
    Dim fnt As Font = New System.Drawing.Font("Calibri", 30.0!, _
        System.Drawing.FontStyle.Bold, _
        System.Drawing.GraphicsUnit.Point, CType(0, Byte))
    'Create CAPTCHA object with custom width, height and fontstyle
    Dim captcha = New Captcha(180, 55, fnt)
    'Start CAPTCHA generation
    captcha.GenerateCaptcha()
    'Save generated CAPTCHA (image) on target folder (CAPTCHAImage) 
    'located at your application root folder.
    captcha.CaptchaImage.Save(Server.MapPath("CAPTCHAImage/") & _
                              strFile, Drawing.Imaging.ImageFormat.Jpeg)
    'Display CAPTCHA (image) on your webpage
    imgCaptcha.ImageUrl = "CAPTCHAImage/" & strFile
    imgCaptcha.ToolTip = "Add this code into Verify textbox"
    'Store CAPTCHA (image) value into Session, becuse that will be
    'used for validating a CAPTCHA (image) with Session
    Session("CAPTCHA") = captcha.CaptchaValue
End Sub

使用该类

  1. 显示 captcha 并将用户输入与类中存储的值进行验证。
  2. 将生成的位图保存到磁盘,以便在 ASP.NET 应用程序中将其显示给 Web 用户。
  3. 如果用户请求,您还可以重新生成该值。
#Region "Captcha Generation Code"
''' <summary>
''' Generates a new captcha value and graphic for the class
''' </summary>
''' <remarks>
Public Sub GenerateCaptcha()
    '//1. CAPTCHA default property
    '------------------------------------------------------------
    'If you could not set the Font,Height and Width property 
    'of CAPTCHA, it will not be generate any images
    If _captchaFont Is Nothing OrElse _captchaHeight = 0 _
                    OrElse _captchaWidth = 0 Then
        Exit Sub
    End If

    Dim strValue As String = ""
    Dim captchaDigit As String = ""
    'This following line is used to decide whether alphabet 
    '(character that includes A-Z, a-z)
    'should be displayed or not
    Dim strAlphaDisplay As String = "0100110100"

    '//2. Digit character in CAPTCHA graphic
    '------------------------------------------------------------
    'RandomValue.Next(10000, 1000000).ToString will be return 
    '6 characters string between (10000 to 1000000) randomly.
    captchaDigit = RandomValue.Next(10000, 1000000).ToString

    '//3. Create Bitmap object
    '------------------------------------------------------------
    'We must create a Bitmap object on witch we draw a CAPTCHA graphic.
    'New Bitmap(_captchaWidth, _captchaHeight)         
    'The parameters represent the height and weight of the bitmap. 
    'They are not important right now, we will modify them later
    _captchaImage = New Bitmap(_captchaWidth, _captchaHeight)

    Using CaptchaGraphics As Graphics = Graphics.FromImage(CaptchaImage)
        '//4. Alphabets character in CAPTCHA graphic
        '--------------------------------------------------------
        'Allows you to select from a large variety of preset 
        'patterns to paint with, rather than a solid color.
        'The following code to create a HatchBrush that 
        'paints with a "SmallGrid" pattern,
        'using "DimGray" as the forecolor 
        'and "WhiteSmoke" as the backcolor. 
        Using BackgroundBrush As New Drawing2D.HatchBrush(_
              Drawing2D.HatchStyle.SmallGrid, Color.DimGray, Color.WhiteSmoke)
            CaptchaGraphics.FillRectangle(BackgroundBrush, 0, 0, _
                            _captchaWidth, _captchaHeight)
        End Using

        'Calculate horizontal space between each Character.
        Dim CharacterSpacing As Integer = (_captchaWidth \ captchaDigit.Length) - 1
        'Variable declaration that will be used later
        Dim HorizontalPosition As Integer
        Dim MaxVerticalPosition As Integer
        Dim rndbBrush As New Random
        Dim rndAlphabet As New Random
        Dim rndAlphaDisplay As New Random

        For Each CharValue As Char In captchaDigit.ToCharArray

            '//5. Alphabets character in CAPTCHA graphic
            '----------------------------------------------------
            'rndAlphaDisplay.Next(0, 9) will be return one digit between 0-9
            Dim intAlphaDisplay As Integer = rndAlphaDisplay.Next(0, 9)
            'Now compared return digit with static value ("0100110100")index, 
            'if it will return "1" then i generate random number between (0 to 51)
            'the length of Capital Letters (A-Z) = 26 
            'and Small  Letters (a-z) = 26 (26+26=52)
            If strAlphaDisplay.ToCharArray(intAlphaDisplay, 1) = "1" Then
                CharValue = alphabets(rndAlphabet.Next(0, 51))
            End If

            '//6. Stored generated CAPTCHA characters
            '----------------------------------------------------
            strValue = strValue & CharValue

            'rndbBrush.Next(0, 139) will return a color index 
            '(which is stored in "colors" ArrayList).
            'All the colors (140 colors starting from 
            '"AliceBlue" to "YellowGreen")
            '----------------------------------------------------
            Dim intRand As Integer = rndbBrush.Next(0, 139)

            '//7. Set the font color of Character.
            '----------------------------------------------------
            'The color of the brush would be the color of the character .
            'get the drawing brush and where we're going to draw.
            Dim brush As Brush = _
              New SolidBrush(ColorTranslator.FromHtml(colors(intRand)))

            '//8. Set the position of Character.
            '----------------------------------------------------
            MaxVerticalPosition = _captchaHeight - Convert.ToInt32(_
               CaptchaGraphics.MeasureString(CharValue, _captchaFont).Height)
            'Draw the Character.
            CaptchaGraphics.DrawString(CharValue, _captchaFont, brush, _
               HorizontalPosition, RandomValue.Next(0, MaxVerticalPosition))
            'Now set the horizontal position of next upcoming Character.
            HorizontalPosition += CharacterSpacing + RandomValue.Next(-1, 1)

            'Clear brush
            brush.Dispose()
        Next

        '//9. Set noise in CAPTCHA graphic.
        '--------------------------------------------------------
        'Image noise is the random variation of colors
        'like (Red, Blue, Green and Yellow)
        'information in images produced by following method
        'Just it is used for increasing complexity 
        'and readability of the image.
        Dim RndmValue As New Random
        Dim start As Integer = RndmValue.Next(1, 4)
        For Counter As Integer = 0 To 24
            CaptchaGraphics.FillEllipse(Brushes.Red, _
                RandomValue.Next(start, _captchaWidth), _
                RandomValue.Next(1, _captchaHeight), _
                RandomValue.Next(1, 4), RandomValue.Next(2, 5))
            start = RndmValue.Next(1, 4)
            CaptchaGraphics.FillEllipse(Brushes.Blue, _
                RandomValue.Next(start, _captchaWidth), _
                RandomValue.Next(1, _captchaHeight), _
                RandomValue.Next(1, 6), RandomValue.Next(2, 7))
            start = RndmValue.Next(1, 4)
            CaptchaGraphics.FillEllipse(Brushes.Green, _
                RandomValue.Next(start, _captchaWidth), _
                RandomValue.Next(1, _captchaHeight), _
                RandomValue.Next(1, 4), RandomValue.Next(2, 6))
            start = RndmValue.Next(1, 4)
            CaptchaGraphics.FillEllipse(Brushes.Yellow, _
                RandomValue.Next(start, _captchaWidth), _
                RandomValue.Next(1, _captchaHeight), _
                RandomValue.Next(1, 5), RandomValue.Next(2, 6))
        Next

            '//10. Clear pending CAPTCHA graphics.
            '----------------------------------------------------
            ' Finally, the Flush method forces all pending 
            ' operations on the Graphics object to finish.
            CaptchaGraphics.Flush()
            _captchaFont.Dispose()
        End Using

        'Set the CAPTCHA graphic answer and image 
        'to CaptchaValue and CaptchaImage
        CaptchaValue = strValue
        CaptchaImage = _captchaImage
    End Sub
#End Region

关注点

让我们来看一下此例程的一些细节。

  • HatchBrush 对象用于绘制网格背景。
  • 从随机生成的数字中提取的字符逐个绘制到图形上,并沿垂直轴随机放置,并在水平轴上略微倾斜。
  • Graphics 对象的 FillEllipse 方法用于在图形上的 50 个不同随机点创建噪点。

如果您对此示例有任何问题或想法,请在下方留言告诉我。

© . All rights reserved.