123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- using Microsoft.Extensions.Caching.Memory;
- using System.DrawingCore;
- using System.DrawingCore.Imaging;
- using System.Text;
- using YBEE.EQM.Core;
- namespace YBEE.EQM.Application
- {
- /// <summary>
- /// 常规验证码
- /// </summary>
- public class GeneralCaptchaService : IGeneralCaptchaService, ITransient
- {
- private readonly IMemoryCache _memoryCache;
- public GeneralCaptchaService(IMemoryCache memoryCache)
- {
- _memoryCache = memoryCache;
- }
- /// <summary>
- /// 生成验证码图片
- /// </summary>
- /// <param name="length">验证码长度</param>
- /// <param name="width">图片宽度</param>
- /// <param name="height">图片高度</param>
- /// <param name="fontSize">字体大小</param>
- /// <returns></returns>
- public GeneralCaptchaOutput CreateCaptchaImage(int length = 6, int width = 260, int height = 36, int fontSize = 22)
- {
- var rtnResult = new GeneralCaptchaOutput();
- var code = GenerateRandom(length); // 随机字符串集合
- rtnResult.ImageBase64 = Convert.ToBase64String(Draw(code, width, height, fontSize));
- rtnResult.Token = Guid.NewGuid().ToString();
- // 缓存验证码正确位置集合
- var cacheOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(120));
- _memoryCache.Set(CommonConst.CACHE_KEY_CODE + rtnResult.Token, code, cacheOptions);
- return rtnResult;
- }
- /// <summary>
- /// 验证码验证
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- public GeneralCaptchaOutput CheckCode(GeneralCaptchaInput input)
- {
- var res = new GeneralCaptchaOutput();
- var code = _memoryCache.Get(CommonConst.CACHE_KEY_CODE + input.Token);
- if (code == null)
- {
- res.Code = 1;
- res.Message = "验证码已失效,请重新获取";
- return res;
- }
- if (string.Compare(input.CaptchaCode, (string)code, true) != 0)
- {
- res.Code = 2;
- res.Message = "验证码错误";
- return res;
- }
- _memoryCache.Remove(CommonConst.CACHE_KEY_CODE + input.Token);
- res.Code = 0;
- res.Message = "验证成功";
- return res;
- }
- #region 私有方法
- /// <summary>
- /// 绘制验证码
- /// </summary>
- /// <param name="code"></param>
- /// <param name="codeW"></param>
- /// <param name="codeH"></param>
- /// <param name="fontSize"></param>
- /// <returns></returns>
- private static byte[] Draw(string code, int codeW, int codeH, int fontSize)
- {
- // 颜色列表,用于验证码、噪线、噪点
- Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
- // 字体列表,用于验证码
- string[] fonts = new[] { "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" };
- using (var bmp = new Bitmap(codeW, codeH))
- using (var g = Graphics.FromImage(bmp))
- using (var ms = new MemoryStream())
- {
- g.Clear(Color.White);
- var rnd = new Random();
- // 画噪线
- for (int i = 0; i < 4; i++)
- {
- int x1 = rnd.Next(codeW);
- int y1 = rnd.Next(codeH);
- int x2 = rnd.Next(codeW);
- int y2 = rnd.Next(codeH);
- var clr = color[rnd.Next(color.Length)];
- g.DrawLine(new Pen(clr), x1, y1, x2, y2);
- }
- // 画验证码字符串
- string fnt;
- Font ft;
- for (int i = 0; i < code.Length; i++)
- {
- fnt = fonts[rnd.Next(fonts.Length)];
- ft = new Font(fnt, fontSize);
- var clr = color[rnd.Next(color.Length)];
- g.DrawString(code[i].ToString(), ft, new SolidBrush(clr), (float)i * 24 + 3, (float)0);
- }
- // 将验证码图片写入内存流
- bmp.Save(ms, ImageFormat.Png);
- return ms.ToArray();
- }
- }
- /// <summary>
- /// 生成验证码
- /// </summary>
- /// <param name="length"></param>
- /// <returns></returns>
- private static string GenerateRandom(int length)
- {
- var chars = new StringBuilder();
- // 验证码的字符集,去掉了一些容易混淆的字符
- char[] character = { '2', '3', '4', '5', '6', '8', '9', 'a', 'b', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y' };
- Random rnd = new();
- // 生成验证码字符串
- for (int i = 0; i < length; i++)
- {
- chars.Append(character[rnd.Next(character.Length)]);
- }
- return chars.ToString();
- }
- #endregion
- }
- }
|