构建一个.net的干货类库,以便于快速的开发 - 验证码
一个验证码对于一个网站的作用不言而喻,而随着技术的发展验证码的种类也开始多了起来,发展至今很多网站已经不再使用一种验证码,为满足需求程序猿就要写很多的方法来适应需求,今天我就来介绍我之前收集到的验证码的方法写成的一个帮助类,来解决我们日常开发当中的验证码需求问题。
帮助类中验证码是以byte[]的格式返回的,方便使用。
英文字符验证码
- /// <summary>
- /// 英文字符验证码
- /// </summary>
- /// <param name="Code">传出验证码</param>
- /// <param name="CodeLength">验证码字符</param>
- /// <returns></returns>
- public static byte[] GraphCode(out string Code,int CodeLength)
- {
- int Width = ;//默认为100
- int Height = ;//默认为40
- int FontSize = ;//默认为20
- byte[] bytes = GraphCode(out Code, CodeLength, Width, Height, FontSize);
- return bytes;
- }
- /// <summary>
- /// 产生图形验证码。
- /// </summary>
- /// <param name="Code">传出验证码。</param>
- /// <param name="CodeLength">验证码字符。</param>
- /// <param name="Width"></param>
- /// <param name="Height"></param>
- /// <param name="FontSize"></param>
- /// <returns></returns>
- public static byte[] GraphCode(out string Code, int CodeLength, int Width, int Height, int FontSize)
- {
- string code = string.Empty;
- String sCode = String.Empty;
- //顏色列表,用于验证码、噪线、噪点
- Color[] oColors ={
- Color.Black,
- Color.Red,
- Color.Blue,
- Color.Green,
- Color.Orange,
- Color.Brown,
- Color.Brown,
- Color.DarkBlue
- };
- //字体列表,用于验证码
- string[] oFontNames = { "Times New Roman", "MS Mincho", "Book Antiqua", "Gungsuh", "PMingLiU", "Impact" };
- //验证码的字元集
- char[] oCharacter =
- {
- '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',
- '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'
- };
- Random oRnd = new Random();
- Bitmap oBmp = null;
- Graphics oGraphics = null;
- int N1 = ;
- //生成验证码字串
- for (N1 = ; N1 <= CodeLength - ; N1++)
- {
- sCode += oCharacter[oRnd.Next(oCharacter.Length)];
- }
- oBmp = new Bitmap(Width, Height);
- oGraphics = Graphics.FromImage(oBmp);
- oGraphics.Clear(Color.White);
- try
- {
- oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
- Font f = new System.Drawing.Font("宋体", FontSize, (System.Drawing.FontStyle.Bold));
- // 前景色
- Brush b = new System.Drawing.SolidBrush(Color.Black);
- // 背景色
- oGraphics.Clear(Color.White);
- // 填充文字
- for (int i = ; i < sCode.Length; i++)
- {
- oGraphics.DrawString(sCode[i].ToString(), f, b, new Rectangle(i * (FontSize - ), , (FontSize - ), Height));
- }
- // 随机线条
- Pen linePen = new Pen(Color.Gray, );
- Random rand = new Random();
- for (int i = ; i < ; i++)
- {
- int x1 = rand.Next(oBmp.Width);
- int y1 = rand.Next(oBmp.Height);
- int x2 = rand.Next(oBmp.Width);
- int y2 = rand.Next(oBmp.Height);
- oGraphics.DrawLine(linePen, x1, y1, x2, y2);
- }
- // 随机点
- for (int i = ; i < ; i++)
- {
- int x = rand.Next(oBmp.Width);
- int y = rand.Next(oBmp.Height);
- oBmp.SetPixel(x, y, Color.FromArgb(rand.Next(), rand.Next(), rand.Next()));
- }
- Code = sCode;
- //保存图片数据
- MemoryStream stream = new MemoryStream();
- oBmp.Save(stream, ImageFormat.Jpeg);
- //输出图片流
- return stream.ToArray();
- }
- finally
- {
- oGraphics.Dispose();
- }
- }
验证码中的字元集是可以改变的,可以去掉一些容易混淆的字元,我这里使用了全部的字元
数字字符验证码
- /// <summary>
- /// 纯数字图形验证码
- /// </summary>
- /// <param name="Code">传出验证码</param>
- /// <param name="CodeLength">验证码字符</param>
- /// <returns></returns>
- public static byte[] NumCode(out string Code, int CodeLength)
- {
- Code = CreateValidateCode(CodeLength);
- byte[] bytes = CreateValidateGraphic(Code);
- return bytes;
- }
- /// <summary>
- /// 生成验证码
- /// </summary>
- /// <param name="CodeLength">指定验证码的长度</param>
- /// <returns></returns>
- private static string CreateValidateCode(int CodeLength)
- {
- int[] randMembers = new int[CodeLength];
- int[] validateNums = new int[CodeLength];
- string validateNumberStr = "";
- //生成起始序列值
- int seekSeek = unchecked((int)DateTime.Now.Ticks);
- Random seekRand = new Random(seekSeek);
- int beginSeek = (int)seekRand.Next(, Int32.MaxValue - CodeLength * );
- int[] seeks = new int[CodeLength];
- for (int i = ; i < CodeLength; i++)
- {
- beginSeek += ;
- seeks[i] = beginSeek;
- }
- //生成随机数字
- for (int i = ; i < CodeLength; i++)
- {
- Random rand = new Random(seeks[i]);
- int pownum = * (int)Math.Pow(, CodeLength);
- randMembers[i] = rand.Next(pownum, Int32.MaxValue);
- }
- //抽取随机数字
- for (int i = ; i < CodeLength; i++)
- {
- string numStr = randMembers[i].ToString();
- int numCodeLength = numStr.Length;
- Random rand = new Random();
- int numPosition = rand.Next(, numCodeLength - );
- validateNums[i] = Int32.Parse(numStr.Substring(numPosition, ));
- }
- //生成验证码
- for (int i = ; i < CodeLength; i++)
- {
- validateNumberStr += validateNums[i].ToString();
- }
- return validateNumberStr;
- }
- /// <summary>
- /// 创建验证码的图片
- /// </summary>
- /// <param name="validateCode">验证码</param>
- private static byte[] CreateValidateGraphic(string validateCode)
- {
- Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), );
- Graphics g = Graphics.FromImage(image);
- try
- {
- //生成随机生成器
- Random random = new Random();
- //清空图片背景色
- g.Clear(Color.White);
- //画图片的干扰线
- for (int i = ; i < ; 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 Font("Arial", , (FontStyle.Bold | FontStyle.Italic));
- LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(, , image.Width, image.Height),
- Color.Blue, Color.DarkRed, 1.2f, true);
- g.DrawString(validateCode, font, brush, , );
- //画图片的前景干扰点
- for (int i = ; i < ; i++)
- {
- int x = random.Next(image.Width);
- int y = random.Next(image.Height);
- image.SetPixel(x, y, Color.FromArgb(random.Next()));
- }
- //画图片的边框线
- g.DrawRectangle(new Pen(Color.Silver), , , image.Width - , image.Height - );
- //保存图片数据
- MemoryStream stream = new MemoryStream();
- image.Save(stream, ImageFormat.Jpeg);
- //输出图片流
- return stream.ToArray();
- }
- finally
- {
- g.Dispose();
- image.Dispose();
- }
- }
数字与字符混合验证码
- /// <summary>
- /// 生成随机字符串
- /// </summary>
- /// <param name="NumCount"></param>
- /// <returns></returns>
- private static string CreateRandomNum(int NumCount)
- {
- char[] allCharArray =
- {
- '','','','','','','','','',
- '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',
- '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 randomNum = "";
- int temp = -;//记录上次随机数的数值,尽量避免产生几个相同的随机数
- Random rand = new Random();
- for (int i = ; i < NumCount; i++)
- {
- if (temp != -)
- {
- rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
- }
- int t = rand.Next();
- if (temp == t)
- {
- return CreateRandomNum(NumCount);
- }
- temp = t;
- randomNum += allCharArray[t];
- }
- return randomNum;
- }
- /// <summary>
- /// 数字和字符混合验证码
- /// </summary>
- /// <param name="Code">传出字符</param>
- /// <param name="NumCount">字节长度</param>
- /// <param name="Width">图片宽度</param>
- /// <param name="Height">图片长度</param>
- /// <param name="FontSize">文字大小</param>
- /// <returns></returns>
- public static byte[] GNCode(out string Code, int NumCount, int Width, int Height, int FontSize)
- {
- string validateNum = CreateRandomNum(NumCount);
- Code = null;
- if (validateNum == null || validateNum.Trim() == String.Empty)
- return null;
- //生成Bitmap图像
- System.Drawing.Bitmap image = new System.Drawing.Bitmap(Width, Height);
- Graphics g = Graphics.FromImage(image);
- try
- {
- //生成随机生成器
- Random random = new Random();
- //清空图片背景色
- g.Clear(Color.White);
- g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
- Font f = new System.Drawing.Font("宋体", FontSize, (System.Drawing.FontStyle.Bold));
- // 前景色
- Brush b = new System.Drawing.SolidBrush(Color.Black);
- // 背景色
- g.Clear(Color.White);
- // 填充文字
- for (int i = ; i < validateNum.Length; i++)
- {
- g.DrawString(validateNum[i].ToString(), f, b, new Rectangle(i * (FontSize - ), , (FontSize - ), Height));
- }
- // 随机线条
- Pen linePen = new Pen(Color.Gray, );
- Random rand = new Random();
- for (int i = ; i < ; i++)
- {
- int x1 = rand.Next(image.Width);
- int y1 = rand.Next(image.Height);
- int x2 = rand.Next(image.Width);
- int y2 = rand.Next(image.Height);
- g.DrawLine(linePen, x1, y1, x2, y2);
- }
- // 随机点
- for (int i = ; i < ; i++)
- {
- int x = rand.Next(image.Width);
- int y = rand.Next(image.Height);
- image.SetPixel(x, y, Color.FromArgb(rand.Next(), rand.Next(), rand.Next()));
- }
- Code = validateNum;
- //保存图片数据
- MemoryStream stream = new MemoryStream();
- image.Save(stream, ImageFormat.Jpeg);
- //输出图片流
- return stream.ToArray();
- }
- finally
- {
- g.Dispose();
- image.Dispose();
- }
- }
数学算式验证码
- /// <summary>
- /// 数学算式的验证码
- /// </summary>
- /// <param name="Code"></param>
- /// <returns></returns>
- public static byte[] MathVerifyCode(out int Code)
- {
- int mathResult = ;
- string expression = null;
- Random rnd = new Random();
- ////生成3个10以内的整数,用来运算
- int operator1 = rnd.Next(, );
- int operator2 = rnd.Next(, );
- int operator3 = rnd.Next(, );
- ////随机组合运算顺序,只做 + 和 - 运算
- switch (rnd.Next(, ))
- {
- case :
- mathResult = operator1 + operator2 + operator3;
- expression = string.Format("{0} + {1} + {2} = ?", operator1, operator2, operator3);
- break;
- case :
- mathResult = operator2 - operator1 + operator3;
- expression = string.Format("{0} - {1} + {2} = ?", operator2, operator1, operator3);
- break;
- default:
- mathResult = operator2 + operator1 - operator3;
- expression = string.Format("{0} + {1} - {2} = ?", operator2, operator1, operator3);
- break;
- }
- Code = mathResult;
- using (Bitmap bmp = new Bitmap(, ))
- {
- using (Graphics graph = Graphics.FromImage(bmp))
- {
- graph.Clear(Color.FromArgb(, , )); ////背景色,可自行设置
- ////画噪点
- for (int i = ; i <= ; i++)
- {
- graph.DrawRectangle(
- new Pen(Color.FromArgb(rnd.Next(, ), rnd.Next(, ), rnd.Next(, ))),
- rnd.Next(, ),
- rnd.Next(, ),
- ,
- );
- }
- ////输出表达式
- for (int i = ; i < expression.Length; i++)
- {
- graph.DrawString(expression.Substring(i, ),
- new Font(FontFamily.GenericSansSerif, , FontStyle.Bold),
- new SolidBrush(Color.FromArgb(rnd.Next(), rnd.Next(), rnd.Next())),
- + i * ,
- rnd.Next(, ));
- }
- ////画边框,不需要可以注释掉
- graph.DrawRectangle(new Pen(Color.Firebrick), , , - , - );
- }
- MemoryStream stream = new MemoryStream();
- bmp.Save(stream, ImageFormat.Jpeg);
- //输出图片流
- return stream.ToArray();
- }
- }
数学算式验证码里面的算式结构是可以改成更复杂的,不过个人觉得加减法已经可以满足日常需求
使用方式
以ASP.NET MVC为例,使用方式很简单,写一个方法,以图片文件的形式输出
- /// <summary>
- /// 验证码
- /// </summary>
- /// <returns></returns>
- public virtual ActionResult VerifyImage()
- {
- string Code = "";
- byte[] bytes = CodeHelper.GNCode(out Code, , , , );
- Session["Code"] = Code;
- return File(bytes, @"image/jpeg");
- }
这里的CodeHelper就是我们写好的验证码帮助类,直接调用
前端放一张图片来显示验证码
- <img src="@Url.Action("VerifyImage")" id="VerifyImage" title="点击换一个">
应用截图
构建一个.net的干货类库,以便于快速的开发 - 验证码的更多相关文章
- 构建一个.net的干货类库,以便于快速的开发 - 前言
前言: 工作已经快两年了,项目也做过不少,不知道大家有没有一个习惯,就是把在做项目过程中那些好的方法记录下来.我觉得这个习惯在开发的过程中还是很有用的,举个例子,我之前做过一个支付宝的支付功能,然后把 ...
- 构建一个.net的干货类库,以便于快速的开发 - 加密
在开发程序的时候,加密是一个程序一个必须的功能,基本上任何程序都会用到加密,而不同的加密方式又适应不同需求,有些加密是不可逆的,最常见是用于用户密码的加密,因为很多时候程序里面不该显示出用户的明文密码 ...
- 构建一个.net的干货类库,以便于快速的开发 - 工具类
相信每一个开发的框架都会有一个工具类,工具类的作用有很多,通常我会将最常用的方法放在工具类里 取得用户IP 取得网站根目录的物理路径 枚举相关 非法关键字检查 绝对路径改为相对路径 获取小数位(四舍五 ...
- 简单使用Laravel-admin构建一个功能强大的后台管理
Laravel-admin可以快速构建一个功能强大的后台,方便快速开发. 以下内容记录简单使用Laravel-admin,以及遇到小错误的解决方法. Laravel-admin 依赖以下环境 需要提前 ...
- 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)
大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...
- 利用 vue-cli 构建一个 Vue 项目
一.项目初始构建 现在如果要构建一个 Vue 的项目,最方便的方式,莫过于使用官方的 vue-cli . 首先,咱们先来全局安装 vue-cli ,打开命令行工具,输入以下命令: $ npm inst ...
- 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)
通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...
- .Net中的AOP系列之构建一个汽车租赁应用
返回<.Net中的AOP>系列学习总目录 本篇目录 开始一个新项目 没有AOP的生活 变更的代价 使用AOP重构 本系列的源码本人已托管于Coding上:点击查看. 本系列的实验环境:VS ...
- 基于Vue2.0+Vue-router构建一个简单的单页应用
爱编程爱分享,原创文章,转载请注明出处,谢谢!http://www.cnblogs.com/fozero/p/6185492.html 一.介绍 vue.js 是 目前 最火的前端框架,vue.js ...
随机推荐
- 在开发过程中,如何在手机上测试vue-cli构建的项目
由于有时候谷歌手机调试与真是的手机环境还是有一定的差距,所以需要在手机上测试项目. 手机上测试vue-cli构建项目方法: 打开项目config/index.js文件,找到module.exports ...
- 推荐系统(1)--splitting approaches for context-aware recommendation
开篇语: 大一的时候.在实验室老师和师兄的带领下.我開始接触推荐系统.时光匆匆,转眼已是大三,因为大三课甚是少.于是便有了时间将自己所学的东西做下总结. 第一篇博客.献给过去三年里带我飞的老师和师兄们 ...
- Servlet的引入
一.分析 此模式有问题: 1.jsp需要呼叫javabean StudentService stuService = new StudentServiceImpl(); List<Student ...
- [办公应用]如何在WORD中让英文网址可以在字符中间换行
有时候我们写文章,存在中英文混合录入的情况.一般情况下,office 2003的word软件中,会自作聪明的避免单词断行显示,也就是说它会默认尽量把一个单词显示在某一行内,从而避免单词被分开.但有时候 ...
- 下面forward和redirect的描述,正确的是(ABCD)
A:forward是服务器将控制权转交给内部服务器对象,由新的对象来全权负责响应用户的请求 B:执行forward时,浏览器不知道服务器所发送的内容从那里来,浏览器地址栏中还是原来的地址 C:执行re ...
- reverse proxy and forward proxy
1 什么是forward proxy 一句话,client的proxy就是forward proxy. 2 什么是reverse proxy 一句话,server的proxy就是reverse pro ...
- Oracle - 查询语句 - 分组函数
/* 分组函数 不能再select子句中出现普通的列,除非这个列在group by中给出 所有的空值都会被分为一组 分组过滤 SELECT FROM WHERE GROUPBY HAVING ORDE ...
- android 自定义View开发实战(六) 可拖动的GridView
1前言 由于项目需求,需要把项目的主界面采用GridView显示,并且需要根据模块优先级支持拖动图标(砍死产品狗).为此,自定义了一个支持拖拽图标的GridView.效果如下: 具体效果如上图 2 可 ...
- 深入探析c# Socket
最近浏览了几篇有关Socket发送消息的文章,发现大家对Socket Send方法理解有所偏差,现将自己在开发过程中对Socket的领悟写出来,以供大家参考. (一)架构 基于TCP协议的Socket ...
- JavaScript-Tool:CKFinder
ylbtech-JavaScript-Tool:CKFinder 1.返回顶部 CKFinder是一个强大而易于使用的Web浏览器的Ajax文件管理器. 其简单的界面使得它直观,快速学习的各类用户,从 ...