开篇
在Winform、ASP.NET Webform 、ASP.NET MVC中一般做登录界面或多或少的要使用到验证码模块,虽然现在生成验证码的技术和方式越来越多,比如我可以直接调用第三方接口来获取验证码,我也可以使用封装好的验证码插件。文字验证,滑块验证等各种验证方式越来越多,但是一些上年纪的ASP.NET项目中依然使用的后台生成验证码的方式,作为最基础的验证码,有必要进行巩固一下。
使用效果图:
1.Winform下
2.ASP.NET下
生成过程
1.生成随机字符
2.添加干扰线、干扰点
3.画边框
4.画随机字符
5.生成验证码图片
代码实现
前奏:主要引用的两个与绘图有关的命名空间
using System.Drawing;
using System.Drawing.Drawing2D;
实例化一个Bitmap位图对象和一个Graphics画板
Bitmap bitmap = new Bitmap(60, 30);//设置宽高
Graphics graphics = Graphics.FromImage(bitmap);//生成画布
graphics.Clear(Color.White);//清空画布
实现:
生成随机字符
string letters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string code = string.Empty;
Random random = new Random();
//生成四位验证码
for (int i = 0; i < 4; i++)
{
code+= letters[random.Next(0, letters.Length)];
}
添加干扰线、干扰点
主要方法:DrawLine(),bitmap.SetPixel(),Color.FromArgb()
我们可以通过调节干扰线、干扰点的个数来调整验证码识别的难易程度
//画二十条干扰线
for (int i = 0; i <20; i++)
{
int x1 = random.Next(bitmap.Width);
int y1 = random.Next(bitmap.Height);
int x2 = random.Next(bitmap.Width);
int y2 = random.Next(bitmap.Height);
graphics.DrawLine(new Pen(Color.Coral), x1, y1, x2, y2);
}
//画200个干扰点
for (int i = 0; i < 200; i++)
{
int x1 = random.Next(bitmap.Width);
int y1 = random.Next(bitmap.Height);
bitmap.SetPixel(x1, y1, Color.FromArgb(random.Next()));//随机颜色填充
}
画边框:
graphics.DrawRectangle(new Pen(Color.Black), new Rectangle(0, 0, bitmap.Width - 1, bitmap.Height - 1));
画生成的随机字符:
主要方法:LinearGradientBrush渐变画刷,DrawString()
LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Rectangle(0, 0, bitmap.Width, bitmap.Height), Color.Blue, Color.Green, 1.4f);
graphics.DrawString(code, new Font("宋体", 20), linearGradientBrush, new PointF(0, 0));
生成验证码图片
以JPEG的格式保存到MemoryStream内存流中
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
若为Web项目可以直接保存到输入输出流中
bitmap.Save(Response.OutputStream, ImageFormat.Jpeg);
完整代码如下:
Bitmap bitmap = new Bitmap(60, 30);
Graphics graphics = Graphics.FromImage(bitmap);//生成画布
graphics.Clear(Color.White);//清空画布
string letters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string code = string.Empty;
Random random = new Random();
//生成四位验证码
for (int i = 0; i < 4; i++)
{
code+= letters[random.Next(0, letters.Length)];
}
//画二十条干扰线
for (int i = 0; i <20; i++)
{
int x1 = random.Next(bitmap.Width);
int y1 = random.Next(bitmap.Height);
int x2 = random.Next(bitmap.Width);
int y2 = random.Next(bitmap.Height);
graphics.DrawLine(new Pen(Color.Coral), x1, y1, x2, y2);
}
//画200个干扰点
for (int i = 0; i < 200; i++)
{
int x1 = random.Next(bitmap.Width);
int y1 = random.Next(bitmap.Height);
bitmap.SetPixel(x1, y1, Color.FromArgb(random.Next()));
}
//画边框
graphics.DrawRectangle(new Pen(Color.Black), new Rectangle(0, 0, bitmap.Width - 1, bitmap.Height - 1));
//实例化渐变画刷
LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Rectangle(0, 0, bitmap.Width, bitmap.Height), Color.Blue, Color.Green, 1.4f);
//填充生成的验证码
graphics.DrawString(code, new Font("宋体", 20), linearGradientBrush, new PointF(0, 0));
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
在不同场合下的使用
1.在Winform中
直接使用控件图片控件并且绑定单击事件来切换生成的验证码图片
2.在Web项目中
我们在img标签的src属性中请求后台的图片数据,一般实现如下效果:
为了避免浏览器使用缓存而导致点击图片不会改变的情况,我们需要在接口地址后面加上一个随机变量(可以采用当前时间戳或者随机数来解决)
<img id="img1" src="/Movie/Create_V_Code" οnclick="ChangeUrl()"/>
<script>
function ChangeUrl() {
let path = "/Movie/Create_V_Code?p=" + new Date().getTime();
$("#img1").prop("src", path);
}
</script>
同时可以将生成的随机码存入Session中,当用户提交数据的时候进行比对校验。
结语
以上就是用C#实现一个简单验证码的全过程,也是一个需要掌握的东西,别哪天妹子问到了,再去扒资料就尴尬啦