blazor 登录验证码简单实现
先看验证码图片效果 属于答题验证码 可以自定义题库
下面代码自带了20以内加减法的几十道题库 基础情况够用 特殊情况自己生成定义 也可以不设置题库 会自动生成 数学算式
先上使用方式 很简单 一个base64字符串显示验证码 一个事件点击刷新验证码
<img src="@vcodeimg" @onclick="e=>reimg()" />
页面对应的cs代码
//base64图片
public string vcodeimg = "";
//生成的问题答案 判断验证码是否成功用的
public string vcode = "";
private void reimg()
{
VerifyCodeSugar v = new VerifyCodeSugar();
//是否随机字体颜色
v.SetIsRandomColor = true;
//随机码的旋转角度
v.SetRandomAngle = 4;
//文字大小
v.SetFontSize = 15;
//背景色
//v.SetBackgroundColor
//前景噪点数量
//v.SetForeNoisePointCount = 3;
//v.SetFontColor =Color.Red;
//...还有更多设置不介绍了
var questionList = new Dictionary<string, string>()
{ {"8+3=?","11" },
{"14-6=?","8" },
{"20-5=?","15" },
{"8-3=?","5" },
{"16-8=?","8" },
{"12-0=?","12" },
{"14-5=?","9" },
{"10-5=?","5" },
{"10-2=?","8" },
{"11-0=?","11" },
{"9-1=?","8" },
{"9+2=?","11" },
{"8-2=?","6" },
{"17-8=?","9" },
{"18-7=?","11" },
{"11+2=?","13" },
{"9-4=?","5" },
{"13+0=?","13" },
{"10+4=?","14" },
{"12-7=?","5" },
{"10-4=?","6" },
{"13-9=?","4" },
{"15-3=?","12" },
{"16-5=?","11" },
{"11-3=?","8" },
{"10-6=?","4" },
{"12-2=?","10" },
{"9+3=?","12" },
{"20-7=?","13" },
{"10+5=?","15" },
{"11-5=?","6" },
{"9+5=?","14" },
{"11-7=?","4" },
{"8-0=?","8" },
{"10-9=?","1" },
{"14+0=?","14" },
{"16-4=?","12" },
{"14-9=?","5" },
{"11-10=?","1" },
{"18-9=?","9" },
{"14-3=?","11" },
{"12+1=?","13" },
{"20-8=?","12" },
{"13-8=?","5" },
{"11-2=?","9" },
{"12+0=?","12" },
{"15-10=?","5" },
{"11-1=?","10" },
{"17-9=?","8" },
{"8-4=?","4" },
{"14-8=?","6" },
{"14-4=?","10" },
{"10+3=?","13" },
{"8-5=?","3" },
{"8-6=?","2" },
{"11-6=?","5" },
{"10+1=?","11" },
{"9+4=?","13" },
{"16-2=?","14" },
{"8+5=?","13" },
{"18-10=?","8" },
{"10-8=?","2" },
{"12+2=?","14" },
{"12-10=?","2" },
{"13-3=?","10" },
{"10+0=?","10" },
{"18-5=?","13" },
{"14-7=?","7" },
{"10-7=?","3" },
{"20-6=?","14" },
{"12-9=?","3" },
{"13+1=?","14" },
{"18-8=?","10" },
{"11+3=?","14" },
{"15-8=?","7" },
{"14-2=?","12" },
{"12-6=?","6" },
{"15-1=?","14" },
{"9+6=?","15" },
{"16-7=?","9" },
{"12-5=?","7" },
{"17-3=?","14" },
{"9-3=?","6" },
{"15-7=?","8" },
{"9-6=?","3" },
{"15-9=?","6" },
{"15-5=?","10" },
{"13-6=?","7" },
{"10-10=?","0" },
{"18-4=?","14" },
};
var questionItem = v.GetQuestion(questionList);//不赋值为随机验证码 例如: 1*2=? 或者4位数字随机这种
v.SetVerifyCodeText = questionItem.Key;//指定验证文本
vcode = questionItem.Value;
//输出图片
vcodeimg = "data:image/png;base64," + v.OutputImage();
}
protected override void OnInitialized()
{
reimg();
base.OnInitialized();
}
最后放封装好的类库
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Http;
/// <summary>
/// ** 描述:验证码类
/// ** 创始时间:2015-6-30
/// ** 修改时间:2021-1-20
/// ** 创始人:sunkaixuan
/// ** 修改人:_ Toling
/// </summary>
public class VerifyCodeSugar
{
private Random objRandom = new Random();
#region setting
/// <summary>
/// //验证码长度
/// </summary>
public int SetLength = 4;
/// <summary>
/// 验证码字符串
/// </summary>
public string SetVerifyCodeText { get; set; }
/// <summary>
/// 是否加入小写字母
/// </summary>
public bool SetAddLowerLetter = false;
/// <summary>
/// 是否加入大写字母
/// </summary>
public bool SetAddUpperLetter = false;
/// <summary>
/// 字体大小
/// </summary>
public int SetFontSize = 18;
/// <summary>
/// //字体颜色
/// </summary>
public Color SetFontColor = Color.Blue;
/// <summary>
/// 字体类型
/// </summary>
public string SetFontFamily = "Verdana";
/// <summary>
/// 背景色
/// </summary>
public Color SetBackgroundColor = Color.AliceBlue;
/// <summary>
/// 前景噪点数量
/// </summary>
public int SetForeNoisePointCount = 2;
/// <summary>
/// 随机码的旋转角度
/// </summary>
public int SetRandomAngle = 40;
/// <summary>
/// 是否随机字体颜色
/// </summary>
public bool SetIsRandomColor = false;
/// <summary>
/// 图片宽度
/// </summary>
private int SetWith
{
get
{
return this.SetVerifyCodeText.Length * SetFontSize;
}
}
/// <summary>
/// 图片高度
/// </summary>
private int SetHeight
{
get
{
return Convert.ToInt32((60.0 / 100) * SetFontSize + SetFontSize);
}
}
#endregion
#region Constructor Method
public VerifyCodeSugar()
{
this.GetVerifyCodeText();
}
#endregion
#region Private Method
/// <summary>
/// 得到验证码字符串
/// </summary>
private void GetVerifyCodeText()
{
//没有外部输入验证码时随机生成
if (String.IsNullOrEmpty(this.SetVerifyCodeText))
{
StringBuilder objStringBuilder = new StringBuilder();
//加入数字1-9
for (int i = 1; i <= 9; i++)
{
objStringBuilder.Append(i.ToString());
}
//加入大写字母A-Z,不包括O
if (this.SetAddUpperLetter)
{
char temp = ' ';
for (int i = 0; i < 26; i++)
{
temp = Convert.ToChar(i + 65);
//如果生成的字母不是'O'
if (!temp.Equals('O'))
{
objStringBuilder.Append(temp);
}
}
}
//加入小写字母a-z,不包括o
if (this.SetAddLowerLetter)
{
char temp = ' ';
for (int i = 0; i < 26; i++)
{
temp = Convert.ToChar(i + 97);
//如果生成的字母不是'o'
if (!temp.Equals('o'))
{
objStringBuilder.Append(temp);
}
}
}
//生成验证码字符串
{
int index = 0;
for (int i = 0; i < SetLength; i++)
{
index = objRandom.Next(0, objStringBuilder.Length);
this.SetVerifyCodeText += objStringBuilder[index];
objStringBuilder.Remove(index, 1);
}
}
}
}
/// <summary>
/// 得到验证码图片
/// </summary>
private Bitmap GetVerifyCodeImage()
{
Bitmap result = null;
//创建绘图
result = new Bitmap(SetWith, SetHeight);
using (Graphics objGraphics = Graphics.FromImage(result))
{
objGraphics.SmoothingMode = SmoothingMode.HighQuality;
//清除整个绘图面并以指定背景色填充
objGraphics.Clear(this.SetBackgroundColor);
//创建画笔
using (SolidBrush objSolidBrush = new SolidBrush(this.SetFontColor))
{
this.AddForeNoisePoint(result);
this.AddBackgroundNoisePoint(result, objGraphics);
//文字居中
StringFormat objStringFormat = new StringFormat(StringFormatFlags.NoClip);
objStringFormat.Alignment = StringAlignment.Center;
objStringFormat.LineAlignment = StringAlignment.Center;
//字体样式
Font objFont = new Font(this.SetFontFamily,
objRandom.Next(this.SetFontSize - 3, this.SetFontSize), FontStyle.Regular);
//验证码旋转,防止机器识别
char[] chars = this.SetVerifyCodeText.ToCharArray();
for (int i = 0; i < chars.Length; i++)
{
//转动的度数
float angle = objRandom.Next(-this.SetRandomAngle, this.SetRandomAngle);
objGraphics.TranslateTransform(12, 12);
objGraphics.RotateTransform(angle);
objGraphics.DrawString(chars[i].ToString(),
objFont, objSolidBrush, -2, 2, objStringFormat);
objGraphics.RotateTransform(-angle);
objGraphics.TranslateTransform(2, -12);
}
}
}
return result;
}
/// <summary>
/// 添加前景噪点
/// </summary>
/// <param name="objBitmap"></param>
private void AddForeNoisePoint(Bitmap objBitmap)
{
for (int i = 0; i < objBitmap.Width * this.SetForeNoisePointCount; i++)
{
objBitmap.SetPixel(objRandom.Next(objBitmap.Width),
objRandom.Next(objBitmap.Height), this.SetFontColor);
}
}
/// <summary>
/// 添加背景噪点
/// </summary>
/// <param name="objBitmap"></param>
/// <param name="objGraphics"></param>
private void AddBackgroundNoisePoint(Bitmap objBitmap, Graphics objGraphics)
{
using (Pen objPen = new Pen(Color.Azure, 0))
{
for (int i = 0; i < objBitmap.Width * 2; i++)
{
objGraphics.DrawRectangle(objPen, objRandom.Next(objBitmap.Width),
objRandom.Next(objBitmap.Height), 1, 1);
}
}
}
/// <summary>
/// 获取随机颜色
/// </summary>
/// <returns></returns>
private Color GetRandomColor()
{
Random RandomNum_First = new Random((int)DateTime.Now.Ticks);
// 对于C#的随机数,没什么好说的
System.Threading.Thread.Sleep(RandomNum_First.Next(50));
Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks);
// 为了在白色背景上显示,尽量生成深色
int int_Red = RandomNum_First.Next(256);
int int_Green = RandomNum_Sencond.Next(256);
int int_Blue = (int_Red + int_Green > 400) ? 0 : 400 - int_Red - int_Green;
int_Blue = (int_Blue > 255) ? 255 : int_Blue;
return Color.FromArgb(int_Red, int_Green, int_Blue);
}
#endregion
#region Public Method
/// <summary>
/// 输出验证码图片
/// </summary>
/// <returns>输出是否成功</returns>
public string OutputImage()
{
string result = "";
if (this.SetIsRandomColor)
{
this.SetFontColor = GetRandomColor(); ;
}
using (Bitmap objBitmap = this.GetVerifyCodeImage())
{
if (objBitmap != null)
{
using (MemoryStream objMS = new MemoryStream())
{
objBitmap.Save(objMS, ImageFormat.Jpeg);
result = Convert.ToBase64String(objMS.ToArray());
}
}
}
return result;
}
/// <summary>
/// 获取问题
/// </summary>
/// <param name="questionList">默认数字加减验证</param>
/// <returns></returns>
public KeyValuePair<string, string> GetQuestion(Dictionary<string, string> questionList = null)
{
if (questionList == null)
{
questionList = new Dictionary<string, string>();
var operArray = new string[] { "+", "*", "num" };
var left = objRandom.Next(0, 10);
var right = objRandom.Next(0, 10);
var oper = operArray[objRandom.Next(0, operArray.Length)];
if (oper == "+")
{
string key = string.Format("{0}+{1}=?", left, right);
string val = (left + right).ToString();
questionList.Add(key, val);
}
else if (oper == "*")
{
string key = string.Format("{0}×{1}=?", left, right);
string val = (left * right).ToString();
questionList.Add(key, val);
}
else
{
var num = objRandom.Next(1000, 9999); ;
questionList.Add(num.ToString(), num.ToString());
}
}
return questionList.ToList()[objRandom.Next(0, questionList.Count)];
}
#endregion
}