作web总会要用到验证码!刚开始感觉这个东西挺难的,慢慢的感觉这个其实比较简单,只要写多了,感觉也就那么回事。我对他的理解是,首先要搞清实现他的一个基本思路,然后了解实现他的个别方法。这个就够了,没必要可以刻意记忆,以后要用到时,翻开代码,看一下。基本就知道怎么回事了。不过我还是总自己写过的几个验证码归结一下。
1,定义一个方法,生成验证码
public class Common { /// <summary> /// 生成验证字符 /// </summary> /// <param name="len">验证字符的长度</param> /// <returns></returns> public static string ValidateCode(int len) { string Charscode = "abcdefghijklmopqrstuvwxyz123456789";//定义生成验证码的字符串 Random r = new Random(DateTime.Now.Millisecond); string resultCode = "";//用于存放生成的验证码 for (int i = 0; i < len; i++) { resultCode += Charscode[r.Next(len)]; } return resultCode; } /// <summary> /// 将指定的验证字符绘制在特定的场景中 /// </summary> /// <param name="validateCode">验证字符</param> /// <returns></returns> public static Byte[] CreateValidateCode(string validateCode) { //场景对象 Bitmap bmp = new Bitmap(validateCode.Length * 12, 22); //根据场景构造绘图对象 Graphics g = Graphics.FromImage(bmp); g.Clear(Color.White);//清除场景背景色并用白色替代 //绘制场景时所需的参数对象 Font f=new Font("Arial",12f,FontStyle.Bold|FontStyle.Italic); Rectangle rg=new Rectangle(0,0,bmp.Width,bmp.Height); LinearGradientBrush brush=new LinearGradientBrush(rg,Color.Red,Color.Green,1.2f,true); Pen p=new Pen(Color.Silver); //设置绘图的画笔 //定义随机数 Random r = new Random(DateTime.Now.Millisecond); //绘制干扰线 for(int i=0;i<25;i++) { int StartX=r.Next(bmp.Width); int StartY=r.Next(bmp.Height); int EndX=r.Next(bmp.Width); int EndY=r.Next(bmp.Height); g.DrawLine(p, StartX, StartY, EndX, EndY); //绘线 } //绘制干扰点 for (int i = 0; i < 25; i++) { int x=r.Next(bmp.Width); int y=r.Next(bmp.Height); int red=r.Next(255); int green=r.Next(255); int blue=r.Next(255); bmp.SetPixel(x, y, Color.FromArgb(red, green, blue)); } //将字符串绘制到场景中 g.DrawString(validateCode, f, brush, 3, 3); //创建用于保存图片的缓冲流 System.IO.MemoryStream ms=new System.IO.MemoryStream(); //将图片保存到缓冲区中 bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); bmp.Dispose(); return ms.ToArray(); } //调用CreateValidateCode方法,生成验证码 public ActionResult CreateValidateCode() { string validatecode = ValidateCode(5); Session["sn"] = validatecode; Byte[] b = CreateValidateCode(validatecode); return File(b, "image/jpeg"); } }
2,使用一般处理程序(HttpHandler)
一般处理程序WaterMark.ashx的代码:
<%@ WebHandler Language="C#" Class="WaterMark" %> using System; using System.Web; using System.Drawing; using System.Drawing.Drawing2D; using System.Web.SessionState; public class WaterMark : IHttpHandler, IRequiresSessionState // 要使用session必须实现该接口,记得要导入System.Web.SessionState命名空间 { public void ProcessRequest(HttpContext context) { string checkCode = GenCode(5); // 产生5位随机字符 context.Session["Code"] = checkCode; //将字符串保存到Session中,以便需要时进行验证 System.Drawing.Bitmap image = new System.Drawing.Bitmap(70, 22); Graphics g = Graphics.FromImage(image); try { //生成随机生成器 Random random = new Random(); //清空图片背景色 g.Clear(Color.White); // 画图片的背景噪音线 int i; for (i = 0; i < 25; i++) { int x1 = random.Next(image.Width); int x2 = random.Next(image.Width); int y1 = random.Next(image.Height); int y2 = random.Next(image.Height); g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); } Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold)); 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); g.DrawString(checkCode, font, brush, 2, 2); //画图片的前景噪音点 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1); System.IO.MemoryStream ms = new System.IO.MemoryStream(); image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); context.Response.ClearContent(); context.Response.ContentType = "image/Gif"; context.Response.BinaryWrite(ms.ToArray()); } finally { g.Dispose(); image.Dispose(); } } /// <summary> /// 产生随机字符串 /// </summary> /// <param name="num">随机出几个字符</param> /// <returns>随机出的字符串</returns> private string GenCode(int num) { string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//"的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严"; char[] chastr = str.ToCharArray(); // string[] source ={ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#", "$", "%", "&", "@" }; string code = ""; Random rd = new Random(); int i; for (i = 0; i < num; i++) { //code += source[rd.Next(0, source.Length)]; code += str.Substring(rd.Next(0, str.Length), 1); } return code; } public bool IsReusable { get { return false; } } }
然后在页面中的img标签中src属性指定到这个一般处理程序即可
验证码:<img src="Handler/WaterMark.ashx" id="vimg" alt=" 单击可更换内容" onclick="change()" />
3,使用ASP.NET的代码后置生成验证码
using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.Drawing; using System.IO; namespace JXC.Admin.inc { public partial class verifycode : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if(!ispostback) { this.CreateCode(this.CreateStr()); Session["check_code"] = CreateStr(); } } protected string CreateStr() { string str = ""; Random random = new Random(); str = random.Next(1000,9999).ToString(); return str; } protected void CreateCode(string code) { if (code.Length == 0) return; Random random = new Random(); Bitmap map = new Bitmap(4*14,30);//定义一个宽度为4*13,高度为30像素的位图 Graphics g = Graphics.FromImage(map); g.Clear(Color.White); g.DrawRectangle(new Pen(Color.Gray), 0, 0, map.Width - 1, map.Height - 1);//进行描边 //...开始写字 Matrix matrix;//声明用来操作矩阵的类 LinearGradientBrush brush = new LinearGradientBrush(new Point(0, 0), new Point(map.Width, map.Height), Color.Red, Color.Green); for (int j = 0; j < code.Length; j++) { string schar = code.Substring(j,1); matrix = g.Transform;//获取当前绘图的世界坐标系。 float shearx = 0.0F; float sheary = 0.0F; matrix.Shear(shearx,sheary); g.Transform = matrix; g.DrawString(schar,new Font("黑体",14.0f,FontStyle.Bold),brush,new PointF(0.0f+(13.0f*j),random.Next(30-20))); } //画干扰线 int x1=random.Next(map.Width); int y1=random.Next(map.Height); int x2=random.Next(map.Width); int y2=random.Next(map.Height); g.DrawLine(new Pen(Color.Black),new Point(x1,y1),new Point(x2,y2)); //画干扰点 for(int i=0;i<10;i++) { map.SetPixel(random.Next(map.Width),random.Next(map.Height),Color.FromArgb(random.Next(255),random.Next(255),random.Next(255))); } Response.Clear(); MemoryStream stream=new MemoryStream(); map.Save(stream,ImageFormat.Gif); Response.ContentType="image/Gif"; Response.BinaryWrite(stream.ToArray()); } } }
最后在使用的页面中将img标签的src指定为这个页面文件.指定时需要注意生成验证码的这个文件的路如
<img id="Img1" style="width:65px; height:22px; cursor:hand;" src="../verifycode.aspx" alt="" align="middle"/>