验证码的种类与实现 C#封装类 - .NET MVC WEBFORM
验证码方式
1、随机字母或者数字,纯文本验证码
这种非常容易破解 ,市场上有大量的现成接口或者工具,背景越复杂难度越高。
2、题库验证码
要破解这种验证码,需要人工收集题库才可以破解,可以免疫不是专门针对你一个网站的黑客,所以我偏爱这种验证码
•1+1=? •本论坛的域名是? •今天是星期几? •复杂点的数学运算 但是他到底是不是就不能破解了呢? 缺点:数量有限。破解方式也很简单,多刷新几次,建立题库和对应的答案,用正则从网页里抓取问题,寻找匹配的答案后破解。也有些用随机生成的数学公式,比如 随机数 [+-*/]随机运算符 随机数=?,小学生水平的程序员也可以搞定…… 题库越多高全系数越高
3、干扰型题库验证码
将文字显示进行处理起到干扰效果,就算你有正确题库也不能轻易破解
今天正好身体不舒服请了天假整理了这么一个可以实现上面三种验证码的类
效果图
实现步骤
1、MVC Action 或者 WebForm的 pageLoad写以下代码
public void ValidateImg()
{
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>()
{ {"1+1=?","2"},
{"喜羊羊主角叫什么名字?","喜羊羊" },
{"【我爱你】中间的那个字?","爱" },
}; var questionItem = v.GetQuestion();//不赋值为随机验证码 例如: 1*2=? 这种 //指定验证文本
//v.SetVerifyCodeText v.SetVerifyCodeText = questionItem.Key; Session["VerifyCode"] = questionItem.Value; //输出图片
v.OutputImage(System.Web.HttpContext.Current.Response); }
2、前台设用action或者pageload页面地址,js给src更换url添加随机参数 达到刷新验证码的功能
<img src="/File/ValidateImg" />
3、完整封装类
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 System.Web; namespace Idea.Models
{ /// <summary>
/// 验证码类
/// </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>
/// <param name="objHttpResponse">Http响应实例</param>
/// <returns>输出是否成功</returns>
public bool OutputImage(HttpResponse objHttpResponse)
{
bool result = false;
if (this.SetIsRandomColor)
{
this.SetFontColor = GetRandomColor(); ;
} using (Bitmap objBitmap = this.GetVerifyCodeImage())
{
if (objBitmap != null)
{
using (MemoryStream objMS = new MemoryStream())
{
objBitmap.Save(objMS, ImageFormat.Jpeg); HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ContentType = "image/Jpeg";
HttpContext.Current.Response.BinaryWrite(objMS.ToArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End(); result = true;
}
}
} 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
} }
为嘛就一个类写这么多,没排版博客园不给推荐到首页。。
验证码的种类与实现 C#封装类 - .NET MVC WEBFORM的更多相关文章
- 字符型图片验证码识别完整过程及Python实现
字符型图片验证码识别完整过程及Python实现 1 摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...
- 使用tensorflow搭建自己的验证码识别系统
目录 准备验证码数据 保存为tfrecords文件 验证码训练 学习tensorflow有一段时间了,想做点东西来练一下手.为了更有意思点,下面将搭建一个简单的验证码识别系统. 准备验证码数据 下面将 ...
- 完整的验证码识别流程基于svm(若是想提升,可优化)
字符型图片验证码识别完整过程及Python实现 首先很感觉这篇文章的作者,将这篇文章写的这么好.我呢,也是拿来学习,觉得太好,所以忍不住就进行了转载. 因为我个人现在手上也有个验证码识别的项目,只是难 ...
- 构建一个.net的干货类库,以便于快速的开发 - 验证码
一个验证码对于一个网站的作用不言而喻,而随着技术的发展验证码的种类也开始多了起来,发展至今很多网站已经不再使用一种验证码,为满足需求程序猿就要写很多的方法来适应需求,今天我就来介绍我之前收集到的验证码 ...
- python 验证码 高阶验证
python 验证码 高阶验证 标签: 验证码python 2016-08-19 15:07 1267人阅读 评论(1) 收藏 举报 分类: 其他(33) 目录(?)[+] 字符型图片验证 ...
- 字符识别Python实现 图片验证码识别
字符型图片验证码识别完整过程及Python实现 1 摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...
- [转]恕我直言,在座的各位根本不会写 Java!
导语 自 2013 年毕业后,今年已经是我工作的第 4 个年头了,总在做 Java 相关的工作,终于有时间坐下来,写一篇关于 Java 写法的一篇文章,来探讨一下如果你真的是一个 Java 程序员,那 ...
- 细思极恐-你真的会写java吗?
导语 自2013年毕业后,今年已经是我工作的第4个年头了,总在做java相关的工作,终于有时间坐下来,写一篇关于java写法的一篇文章,来探讨一下如果你真的是一个java程序员,那你真的会写java吗 ...
- 细思极恐-你真的会写java吗?
文章核心 其实,本不想把标题写的那么恐怖,只是发现很多人干了几年java以后,都自认为是一个不错的java程序员了,可以拿着上万的工资都处宣扬自己了,写这篇文章的目的并不是嘲讽和我一样做java的同行 ...
随机推荐
- hdu4747——Mex
1.题目大意:对一个序列的每一个区间求Mex,最后所有的mex相加(mex就是SG的那个),力求nlogn... 2.分析:最近开始刷线段树了,还是有很多不会啊 首先把1-1 1-2 1-- 1-n这 ...
- Docker 容器测试全探索
导读 当我们构建好Docker镜像并利用多套容器共同组合成应用程序,建立起持续交付通道,了解了如何将新创建的镜像纳入到生产或者测试环境当中之后,新的问题来了——我们该如何测试自己的Docker容器?测 ...
- NOIP“对偶”题:还教室
先说一下思路: 方差可以经过恒等变形变成 x12 + x22 + ... + xn2 + 2a(x1 + x2 + ... + xn) + na2 所以维护平方和.连续和即可 平均数我就不再推了…… ...
- phpDocumentor 注释语法详解
PHPDocumentor是强大的代码注释生成器,本文对各个参数进行了简单地的总结: @abstract-------------使用@abstract标记来声明一个方法,类变量或类必须重新定义子类中 ...
- Python面试题库
1.Python输出中文怎么解决 方法一:用encode和decode如:import os.pathimport xlrd,sys Filename=’/home/tom/Desktop/1234. ...
- Python之virtualenv安装
CentOS 7 yum install python-virtualenv virtualenv --no-site-packages testenv #不依赖真实环境的packages用 --no ...
- oracle用户创建及权限设置及表空间
建立表空间: create tablespace portx_data datafile 'D:\oracle_data\portx.dbf' size 50m autoextend on next ...
- 【python】python新手必碰到的问题---encode与decode,中文乱码[转]
转自:http://blog.csdn.net/a921800467b/article/details/8579510 为什么会报错“UnicodeEncodeError:'ascii' codec ...
- ios Coredata 的 rollback undo 等事物处理函数
首先说明 ios 中 NSManagedObjectContext 默认的 undoManager是nil的,就是说 undo 和 redo 都是没用的. 但是 rollback函数和reset函数是 ...
- linux的提示信息--/etc/motd和/etc/issue
/etc/motd 即 message of the day 每次用户登录时,这个文件的内容都会显示在用户的终端上.如果shell支持中文,还可以使用中文,这样看起来更加舒服. 成功登录后,自动输出. ...