C#实现数字验证码

开发环境:VS2019,.NET Core 3.1,ASP.NET Core API

1、建立一个验证码控制器

新建两个方法Create和Check,Create用于创建验证码,Check用于验证它是否有效。

声明一个静态类变量存放列表,列表中存放包含令牌和验证码的对象。

        private static List<VCodeModel> _list = new List<VCodeModel>();

        /// <summary>
        /// 返回一个图形验证码和令牌.
        /// </summary>
        /// <returns></returns>
        /// <remarks>这一步需要生成一个数字,并将数字放入图片中,并返回一个令牌,下次验证的时候需要核对令牌和数字是否对应,这些东西保存到类变量中.</remarks>
        [HttpGet]
        public string Create()
        {
            try
            {
                VCodeModel model = new VCodeModel();
                model.id = Guid.NewGuid().ToString();    // 生成令牌
                var vcode = Utils.GetVCode();    // 生成验证码
                model.code = vcode;
                _list.Add(model);    // 记录到缓存中

                // 返回对象
                VCodeController_Create_Receive result = new VCodeController_Create_Receive();
                result.code = "0";
                result.data = new VCodeController_Create_Receive.Data();
                result.data.id = model.id;
                var image = Utils.DrawImage(vcode);
                var base64 = Utils.BitmapToBase64Str(image);
                result.data.img = base64;
                var json = JsonConvert.SerializeObject(result);
                return json;
            }
            catch (Exception ex)
            {
                _logger.LogError(exception: ex, message: ex.Message);
                ReceiveObject result = new ReceiveObject();
                result.code = "999999";
                result.msg = "系统异常";
                var json = JsonConvert.SerializeObject(result);
                return json;
            }
        }

        /// <summary>
        /// 检查验证码是否有效
        /// </summary>
        /// <param name="id">令牌.</param>
        /// <param name="code">验证码.</param>
        /// <returns></returns>
        [HttpGet]
        public string Check(string id, string code)
        {
            try
            {
                var index = _list.FindIndex(m =>
                {
                    if (m.id.Equals(id) && m.code.Equals(code))
                    {
                        return true;
                    }

                    return false;
                });

                ReceiveObject result = new ReceiveObject();
                if (index >= 0)
                {
                    _list.RemoveAt(index);
                    result.code = "0";
                    result.msg = "验证成功";
                    var json = JsonConvert.SerializeObject(result);
                    return json;
                }
                else
                {
                    result.code = "1";
                    result.msg = "验证失败";
                    var json = JsonConvert.SerializeObject(result);
                    return json;
                }
            }
            catch(Exception ex)
            {
                _logger.LogError(exception: ex, message: ex.Message);
                ReceiveObject result = new ReceiveObject();
                result.code = "999999";
                result.msg = "系统异常";
                var json = JsonConvert.SerializeObject(result);
                return json;
            }
        }

2、建立一个验证码模型

验证码模型类包括:令牌和验证码属性。

再创建一个类存放Create方法返回的对象包括:令牌,验证码图片。

    /// <summary>
    /// VCodeController用到的类变量.
    /// </summary>
    public class VCodeModel
    {
        /// <summary>
        /// 令牌.
        /// </summary>
        public string id { get; set; }

        /// <summary>
        ///验证码.
        /// </summary>
        public string code { get; set; }
    }

    /// <summary>
    /// VCodeController控制器中Create方法的返回对象.
    /// </summary>
    public class VCodeController_Create_Receive : ReceiveObject
    {
        public Data data { get; set; }

        public class Data
        {
            /// <summary>
            /// 令牌.
            /// </summary>
            public string id { get; set; }

            /// <summary>
            /// Base64的验证码图片.
            /// </summary>
            public string img { get; set; }
        }
    }

3、建立一个验证码生成器
创建用于生成4位随机数的方法。

创建将随机数绘制成图片的方法。

        static readonly char[] list = new char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', };

        /// <summary>
        /// 获取随机验证码.
        /// </summary>
        /// <returns></returns>
        public static string GetVCode()
        {
            Random random = new Random();
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < 4; i++)
            {
                var index = random.Next(0, list.Length);
                builder.Append(list[index]);
            }

            return builder.ToString();
        }

        /// <summary>
        /// 绘制验证码的图片.
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static Bitmap DrawImage(string code)
        {
            Color[] list_color =
            {
                Color.FromArgb(240, 230, 140),    // 黄褐色(亮)
                Color.FromArgb(138, 54, 15),    // 黄褐色(暗)
                Color.FromArgb(51, 161, 201),    // 蓝色(亮)
                Color.FromArgb(25, 25, 112),    // 蓝色(暗)
                Color.FromArgb(192, 192, 192),    // 灰白(亮)
                Color.FromArgb(128, 128, 105),    // 灰白(暗)
            };

            Random random = new Random();

            // 创建画板
            Bitmap bitmap = new Bitmap(150, 50);

            // 创建画笔
            Graphics grp = Graphics.FromImage(bitmap);
            grp.Clear(Color.White);    // 设置背景色为白色

            // 绘制噪点
            for (int i = 0; i < random.Next(60, 80); i++)
            {
                int x = random.Next(bitmap.Width);
                int y = random.Next(bitmap.Height);
                grp.DrawLine(new Pen(Color.LightGray, 1), x, y, x + 1, y);
            }

            // 绘制随机的线条
            grp.DrawLine(
                new Pen(list_color[random.Next(list_color.Length)], random.Next(3)),
                new Point(random.Next(bitmap.Width / 2), random.Next(bitmap.Height / 2)),
                new Point(bitmap.Width / 2 + random.Next(bitmap.Width / 2), bitmap.Height / 2 + random.Next(bitmap.Height / 2))
            );

            // 绘制验证码
            for (int i = 0; i < code.Length; i++)
            {
                var item = code[i];
                grp.DrawString(item.ToString(),
                    new Font(FontFamily.GenericSansSerif, 25, FontStyle.Bold),
                    new SolidBrush(list_color[random.Next(list_color.Length)]),
                    x: (150 / 4) * i,
                    y: random.Next(5));
            }

            // 在验证码上绘制噪点
            for (int i = 0; i < random.Next(30, 50); i++)
            {
                int x = random.Next(bitmap.Width);
                int y = random.Next(bitmap.Height);
                grp.DrawLine(new Pen(list_color[random.Next(list_color.Length)], 1), x, y, x + 1, y);
            }

            // 绘制随机的线条
            grp.DrawLine(
                new Pen(list_color[random.Next(list_color.Length)], random.Next(3)),
                new Point(random.Next(bitmap.Width / 2), random.Next(bitmap.Height / 2)),
                new Point(bitmap.Width / 2 + random.Next(bitmap.Width / 2), bitmap.Height / 2 + random.Next(bitmap.Height / 2))
            );

            return bitmap;
        }

        /// <summary>
        /// 将图片对象转成Base64的字符串.
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static string BitmapToBase64Str(Bitmap bitmap)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                bitmap.Save(memoryStream, ImageFormat.Jpeg);
                byte[] bytes = memoryStream.ToArray();
                return Convert.ToBase64String(memoryStream.ToArray());
            }
        }

运行效果:

参考:C# 绘制验证码图片_c#生成验证码图片_耕耘虫的博客-CSDN博客

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值