自绘简易验证码

  注册、登录、修改密码等地方一般都出现要输入验证码,验证码也是防止用户的恶意攻击。例如我们知道一个人的账号,然后就可以不停去尝试出用户的密码(假设密码为全数字,我们可以通过for循环不停的试验),而验证码之所以起到阻止恶意的攻击在于验证码是随机的。

  先看一个简单的验证的制作(一般处理程序): 

 1 <%@ WebHandler Language="C#" Class="Vcode2" %>
2
3 using System;
4 using System.Web;
5 using System.Web.SessionState;
6
7 using System.Drawing;
8 using System.Drawing.Imaging;
9
10 public class Vcode2 : IHttpHandler ,IRequiresSessionState{
11
12 public void ProcessRequest (HttpContext context) {
13 context.Response.ContentType = "image/Jpeg";
14
15 string[] codes = { "a", "b", "c", "d", "e", "f", "g", "h" };//先准备八个string类型的元素
16
17
18 int[] indexs=new int[4];//准备一个有4个元素的int类型数组
19
20 Random ran=new Random();//随机数生成器
21
22 for (int i = 0; i < 4; i++)
23 {
24 int num = ran.Next(0,codes.Length-1);//取随机的0-7的数字(有8个原始数据)
25 indexs[i] = num;//为int数组的四个元素赋值(随机的四个值)
26 }
27
28
29
30 string finalCode = string.Empty;//声明一个string类型的变量
31
32 foreach (int i in indexs)//变量int数组中的4个元素(即上面生成的4个随机数字)
33 {
34 finalCode=finalCode+codes[i];//生成了一个4个字母的字符串(每次去取string数组中的元素)
35 }
36
37 //将验证码保存在Session中,以便检查与用户输入的验证码进行对比
38 context.Session["vCode"] = finalCode;
39
40
41 //将生成好的4位字符串以图片的形式输出到浏览器中
42 using (Bitmap img = new Bitmap(80, 32))
43 {
44 using (Graphics gph = Graphics.FromImage(img))
45 {
46 gph.DrawString(finalCode, new Font("微软雅黑", 12), Brushes.White, 0, 0);
47 img.Save(context.Response.OutputStream,ImageFormat.Jpeg);
48 }
49 }
50
51 }
52
53 public bool IsReusable {
54 get {
55 return false;
56 }
57 }
58
59 }

   

  再看一个带有噪点的验证码:

  

  1 <%@ WebHandler Language="C#" Class="ValidateCode" %>
2
3 using System;
4 using System.Web;
5 using System.Drawing;
6 using System.Web.SessionState;
7
8 public class ValidateCode : IHttpHandler, IRequiresSessionState
9 {
10 HttpContext context;
11
12 //在此文件被访问时自动调用 相当于页面的PageLoad事件
13 public void ProcessRequest (HttpContext context1) {
14 this.context = context1;
15 CreateCheckCodeImage(GenerateCheckCode());
16 }
17
18 #region 生成随机字符串
19 /// <summary>
20 /// 生成随机字符串
21 /// </summary>
22 /// <returns></returns>
23 private string GenerateCheckCode()
24 {
25 int number;
26 char code;
27 string checkCode = String.Empty;
28
29 System.Random random = new Random();
30
31 for (int i = 0; i < 5; i++)
32 {
33 number = random.Next();
34
35 if (number % 2 == 0)
36 code = (char)('0' + (char)(number % 10));
37 else
38 code = (char)('0' + (char)(number % 10));
39 //code = (char)('A' + (char)(number % 26));
40
41 checkCode += code.ToString();
42 }
43
44 //Response.Cookies.Add(new HttpCookie("CheckCode", checkCode));
45 //当生成好随机字符串后,将它保存在Session
46 context.Session["vCode"] = checkCode;//.Add("vCode", checkCode);
47 return checkCode;
48 }
49 #endregion
50
51 /// <summary>
52 /// 根据字符串生成图片
53 /// </summary>
54 /// <param name="checkCode">字符串</param>
55 private void CreateCheckCodeImage(string checkCode)
56 {
57 if (checkCode == null || checkCode.Trim() == String.Empty)
58 return;
59 System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
60 Graphics g = Graphics.FromImage(image);
61
62 try
63 {
64 //生成随机生成器
65 Random random = new Random();
66
67 //清空图片背景色
68 g.Clear(Color.White);
69
70 //画图片的背景噪音线
71 for (int i = 0; i < 25; i++)
72 {
73 int x1 = random.Next(image.Width);
74 int x2 = random.Next(image.Width);
75 int y1 = random.Next(image.Height);
76 int y2 = random.Next(image.Height);
77
78 g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
79 }
80
81 Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
82 System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
83 g.DrawString(checkCode, font, brush, 2, 2);
84
85 //画图片的前景噪音点
86 for (int i = 0; i < 100; i++)
87 {
88 int x = random.Next(image.Width);
89 int y = random.Next(image.Height);
90
91 image.SetPixel(x, y, Color.FromArgb(random.Next()));
92 }
93
94 //画图片的边框线
95 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
96
97 //准备缓存流
98 System.IO.MemoryStream ms = new System.IO.MemoryStream();
99 //将图片流存入缓存流
100 image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
101 //清空相应对象内容
102 context.Response.ClearContent();
103 //设置相应对象内容格式为图片
104 context.Response.ContentType = "image/Gif";
105 //将缓存流中的图片流返回客户端
106 context.Response.BinaryWrite(ms.ToArray());
107 }
108 finally
109 {
110 g.Dispose();//销毁画板
111 image.Dispose();//销毁图片
112 }
113 }
114
115 public bool IsReusable {
116 get {
117 return false;
118 }
119 }
120
121 }

 

  验证码的绘制方式有很多,下面看看如果调用:

  

 1 <tr>
2 <td align="right"><font color="#ff3d00">*</font> <asp:Label ID="lblVcode" runat="server" Text="验证码" ></asp:Label>:
3 </td>
4
5 <td > <asp:TextBox ID="txtValidateCode" runat="server"></asp:TextBox>
6 <asp:RequiredFieldValidator ID="rfvVcode" runat="server"
7 ControlToValidate="txtValidateCode" Display="Dynamic" ErrorMessage="验证码不能为空!">*</asp:RequiredFieldValidator><img id="imgCode" src="ashx/ValidateCode.ashx" style="margin-right:5px;" />
8 <span style="cursor: pointer;" onclick="changeImg();" ><a><font color="red" size="2px">
9 <asp:Label ID="lblChangeVcode" runat="server" Text="换一张"></asp:Label></font></a></span>
10 </td>
11 </tr>

        当点击验证码时,执行js方法changeImg();来获取新的验证码--通过时间差来获取不同的随机数

1 <script type="text/javascript">
2 function changeImg() {
3 var s = (new Date()).getSeconds();
4 document.getElementById("imgCode").src = "ashx/ValidateCode.ashx?i=" + s;
5 }
6 </script>

 

   

posted @ 2012-03-04 19:33  fly_kw  阅读(257)  评论(0编辑  收藏  举报