千家信息网

HTML中如何实现验证码生成类

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,这篇文章给大家分享的是有关HTML中如何实现验证码生成类的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。验证码生成流程图首先,咋们来看一下本次分享的验证码生成类的生成流程图:
千家信息网最后更新 2024年09月22日HTML中如何实现验证码生成类

这篇文章给大家分享的是有关HTML中如何实现验证码生成类的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

验证码生成流程图

首先,咋们来看一下本次分享的验证码生成类的生成流程图:

能看到此图描述的编码生成池对应的是几个不同的编码内容,这里主要根据参数设置允许同时获取不同编码内容,从而到达文字,拼音,汉字组合而成验证码,具体规则设置由参数而定;

» 验证码生成池代码的解析

首先,由上面流程图分析的内容能看出,这个验证码生成池子需要并行获取不同类型验证码数据,才能满足组合的验证码,因此有了下面的代码:

///  /// 创建验证码 ///  /// 1:小写拼音 2:大写拼音 3:数字 4:汉字 ///  public static string CreateCode(string codeType = "1|2|3|4") { var code = string.Empty; try { if (string.IsNullOrWhiteSpace(codeType) || codeType.IndexOf('|') < 0) { codeType = "1|2|3|4"; } var codeTypeArr = codeType.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); var strLen = codeTypeArr.Length; //任务 Task[] taskArr = new Task[strLen]; for (int i = 0; i < strLen; i++) {  var val = codeTypeArr[i];  switch (val)  {  case "1": //小写拼音  taskArr[i] = Task.Factory.StartNew(() => { return GetPinYinOrUpper(false); });  break;  case "2": //大写拼音  taskArr[i] = Task.Factory.StartNew(() => { return GetPinYinOrUpper(); });  break;  case "3": //数字  taskArr[i] = Task.Factory.StartNew(() => { return GetShuZi(); });  break;  case "4": //汉字  taskArr[i] = Task.Factory.StartNew(() => { return GetHanZi(); });  break;  default:  break;  } } //等待完成 30s Task.WaitAll(taskArr, TimeSpan.FromSeconds(30)); foreach (var item in taskArr) {  code += item.Result; } } catch (Exception ex) { code = "我爱祖国"; } return code; }

这里继续使用了关键字Task,来分发任务获取不同的验证码内容,个人认为最主要的还是通过参数设置 string codeType = "1|2|3|4" ,来确定验证码的组合方式,这样也达到了验证码格式的多样性;

把验证代码画到图片上

首先,咋们要明确的是要吧文字画在某个图片上,那么需要用到Graphics关键字,以此来创建画布把咋们的验证编码画到图片上,这里先上代码:

///  /// 生成验证码图片流 ///  /// 验证码文字 ///  public static byte[] CreateValidateCodeStream(string code = "我爱祖国", int fontSize = 18, int width = 0, int height = 0, string fontFamily = "华文楷体") { var bb = new byte[0]; //初始化画布 var padding = 2; var len = code.Length; width = width <= 0 ? fontSize * 2 * (len - 1) + padding * 4 : width; height = height <= 0 ? fontSize * 2 : height; var image = new Bitmap(width, height); var g = Graphics.FromImage(image); try { var random = new Random(); //清空背景色 g.Clear(Color.White); //画横向中间干扰线 var x1 = 0; var y1 = height / 2; var x2 = width; var y2 = y1; g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2); //字体 var font = new Font(fontFamily, fontSize, (FontStyle.Bold | FontStyle.Italic)); var brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),  Color.Blue, Color.DarkRed, 1f, true); //画文字 var stringFomart = new StringFormat(); //垂直居中 stringFomart.LineAlignment = StringAlignment.Center; //水平居中 stringFomart.Alignment = StringAlignment.Center; var rf = new Rectangle(Point.Empty, new Size(width, height)); g.DrawString(code, font, brush, rf, stringFomart); //画图片的前景干扰点 for (int i = 0; i < 100; i++) {  var x = random.Next(image.Width);  var y = random.Next(image.Height);  image.SetPixel(x, y, Color.FromArgb(random.Next())); } //画图片的边框线 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1); //保存图片流 var stream = new MemoryStream(); image.Save(stream, ImageFormat.Jpeg); //输出图片流 bb = stream.ToArray(); } catch (Exception ex) { } finally { g.Dispose(); image.Dispose(); } return bb; }

这个列出画验证码图片方法的关键点:

1. 图片的高和宽度需要设置,这个根据不同页面布局方式而定,所以这里吧高和宽用作参数传递

2. 干扰线:通常验证码图片都以一两条干扰线,主要防止某些恶意用户使用图片识别软件进行不正规破解请求,我这里干扰线只设置了横向居中的一天直线代码如: g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2);

3. 字体:一个好看的字体通常也一种用户体验,因此这里根据需要参数传递字体;

4. 验证代码位于图片纵横向居中,这里的关键代码是:

 var stringFomart = new StringFormat(); //垂直居中 stringFomart.LineAlignment = StringAlignment.Center; //水平居中 stringFomart.Alignment = StringAlignment.Center;

5. g.DrawString(code, font, brush, rf, stringFomart); 主要用来把文字画到图片上,这是最关键的地方

6. 咋们通常都是吧验证码弄成图片流,而不是真的生成一个实体的验证码图片保存到服务器上,不然这样服务器很快就会磁盘不足,所以

 //保存图片流 var stream = new MemoryStream(); image.Save(stream, ImageFormat.Jpeg); //输出图片流 bb = stream.ToArray();

这句的重要性也不可忽视,主要就把画的内容保存到流中方便使用

7. 最后千万不用忘了使用Dispose释放画布

» mvc登录操作测试验证码正确性

有了上面验证码生成类生成好的验证码图片,那么我们还需要测试验证下正确性和效果;下面我们使用mvc架构来做测试,先创建一个验证码测试Action并生成对应试图ValidCode.cshtml文件,然后自定义几个不同格式的验证码获取Action,代码如下:

public FileResult GetValidateCode() { //返回的验证码文字 var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode01() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "1|2|3|4"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode02() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "4|3|2|1"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode03() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "2|2|2|2"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode04() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "4|4|4|4"); return File(bb_code, "image/jpeg"); } public FileResult GetValidateCode05() { var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code, "1|1|1|1"); return File(bb_code, "image/jpeg"); }

感觉上几乎一模一样,只是对应的参数不一样,这里遵循的方法GetValidateCodeStream参数codeType格式是:为空表示自由组合 1:小写拼音 2:大写拼音 3:数字 4:汉字;然后我们往试图中填写如下代码:

神牛 - 验证码实例

全部随机
小写|大写|数字|汉字
汉字|数字|大写|小写
全部大写
全部汉字
全部小写

好了咋们生成下项目,看下效果图如下:

能从图中看到我们验证码格式的不同之处,这也是文章开头说的验证码格式的多样性,当然可能还有其他组成格式请允许我暂时忽略,下面我们来做一个点击图片获取新验证码的功能和点击登录按钮去后台程序判断验证码是否匹配的例子,先来修改试图界面代码如下:

@{ ViewBag.Title = "ValidtCode";}

神牛 - 验证码实例

全部随机
小写|大写|数字|汉字
汉字|数字|大写|小写
全部大写
全部汉字
全部小写

然后在Controller中增加如下登录验证代码:

public JsonResult UserLogin(string code) { var data = new Stage.Com.Extend.StageModel.MoData(); if (string.IsNullOrWhiteSpace(code)) { data.Msg = "验证码不能为空"; return Json(data); } var compareCode = Session["code"]; if (!compareCode.Equals(code)) { data.Msg = "验证码错误"; return Json(data); } data.IsOk = true; data.Msg = "验证码验证成功"; return Json(data); } public FileResult GetValidateCode() { //返回的验证码文字 var code = string.Empty; var bb_code = ValidateCode.GetValidateCodeStream(ref code); var key = "code"; if (Session[key] != null) { Session.Remove(key); } Session[key] = code; return File(bb_code, "image/jpeg"); }

由于我这里无法截动态图,所点击测试获取验证码我这里直接给出线上的一个例子,各位可以试试:http://lovexins.com:1001/home/ValidCode,点击获取新验证码的关键代码是: $(this).attr("src", src); 重新给img元素的scr赋值,不过这里要注意由于浏览器缓存的原因,这里赋值的时候需要加上一个动态参数,我这里是使用时间作为请求参数,因此有了以下的代码: $(this).attr("data-src") + "?t=" + nowTime; 这是特别的地方需要注意;好了咋们来直接测试登陆是否能从后端判断验证码是否正确匹配吧,这里用的是session来保存获取验证码图片返回的验证代码,然后在登陆时候判断用户数据的验证码是否和后台session的验证一样:

验证失败:

验证成功:

好了测试用例就这么多,如果您觉得我这个验证码生成例子还可以并且您希望使用那么请注意,参数的传递,不同得到的验证码格式不同,主要方法是:

///  /// 获取验证码图片流 ///  /// 验证码个数(codeType设置 > codeLen设置) /// 为空表示自由组合 1:小写拼音 2:大写拼音 3:数字 4:汉字 ///  public static byte[] GetValidateCodeStream(ref string code, string codeType = "", int codeLen = 0, int fontSize = 18, int width = 120, int height = 30) { //为空自由组合 if (string.IsNullOrWhiteSpace(codeType)) { for (int i = 0; i < codeLen; i++) {  codeType += rm.Next(1, 5) + "|"; } } code = CreateCode(codeType); return CreateValidateCodeStream(code, fontSize, width: width, height: height); }

感谢各位的阅读!关于"HTML中如何实现验证码生成类"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

0