开篇

   在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#实现一个简单验证码的全过程,也是一个需要掌握的东西,别哪天妹子问到了,再去扒资料就尴尬啦