英语家园

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问移动社区

搜索

如何在网站中的应用验证码技术

发布者: 上官飞飞 | 发布时间: 2007-6-9 02:30| 查看数: 2277| 评论数: 0|

如何在网站中的应用验证码技术验证码应用目的:

  为了防止某些别有用心的用户利用机器人(恶意程序)自动注册、自动登录、恶意灌水、恶意增加数据库访问、用特定程序暴力破解密码,可采用验证码技术。

  

  验证码应用原理:

  浏览器应用HTML标准与网站服务器动态联系,在HTML的表单中,基本上都是使用指定有Action的POST方法。如果不应用验证码方法,将很容易被一些别有用心的人利用机器人程序或者盗用Action的恶意程序,实现其个人勾当。应用验证码技术后,可以保护你的服务器,防止这一问题的发生。

  如果要求用户在输入表单内容的时候,还要识读一个由服务器生成的验证码图片并输入该验证码。当服务器收到这样的表单后,首先将用户提交的验证码与Session值(Session值在生成验证码图片是产生)进行比较,根据比较结果判断用户是否为合理使用网站功能。

  

  验证码应用注意事项:

  为了防止电脑OCR读图程序识别和破解验证码,一般需要在合理范围内适当增加对验证码图片的识别难度。目前常用的方法有:数字和字母混合,扭曲翻转字符,增加背景噪点,添加干扰条纹,随机改变字符在图片上的位置,随机改变背景颜色。在增加识别难度上需要掌握好度,用户太难识别验证码了,会影响用户对网站的使用积极性。

  网站应用验证码后,将增大服务器压力,具体表现在两个方面。一是生成验证码会占用服务器CPU时间,二是应用Session会消耗服务器内存。所以,并不是在网站中到处都用。目前应用的比较多的还是在提交表单中使用。

  

  验证码式样:

  本文示例程序可提供的式样及可实现的功能:

  标准式样:

  背景颜色随机变化式样;

  干扰线条随机变化式样;

  干扰噪点随机变化式样;

  扭曲程度随机变化式样;

  首字符位置随机变化式样;

  随机增加3D阴影式样;

  字符数量随机变化式样;

  字体大小随机变化式样;

  

  验证码生成方法:

  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

最新评论

快速回复 返回顶部 返回列表