首页 > 技术文章 > 验证码生成类

hua-nuo 2020-05-09 16:57 原文

验证码生成类

 
 
1.一般处理程序
/// 验证码生成类
/// </summary>
public class verify_code : IHttpHandler, IRequiresSessionState
{
 
public void ProcessRequest(HttpContext context)
{
int codeW = 80;
int codeH = 22;
int fontSize = 16;
string chkCode = string.Empty;
//颜色列表,用于验证码、噪线、噪点
Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
//字体列表,用于验证码
string[] font = { "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" };
//验证码的字符集,去掉了一些容易混淆的字符
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 Random();
//生成验证码字符串
for (int i = 0; i < 4; i++)
{
chkCode += character[rnd.Next(character.Length)];
}
//写入Session
context.Session[DTKeys.SESSION_CODE] = chkCode;
//创建画布
Bitmap bmp = new Bitmap(codeW, codeH);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
//画噪线
for (int i = 0; i < 1; i++)
{
int x1 = rnd.Next(codeW);
int y1 = rnd.Next(codeH);
int x2 = rnd.Next(codeW);
int y2 = rnd.Next(codeH);
Color clr = color[rnd.Next(color.Length)];
g.DrawLine(new Pen(clr), x1, y1, x2, y2);
}
//画验证码字符串
for (int i = 0; i < chkCode.Length; i++)
{
string fnt = font[rnd.Next(font.Length)];
Font ft = new Font(fnt, fontSize);
Color clr = color[rnd.Next(color.Length)];
g.DrawString(chkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * 18 + 2, (float)0);
}
//画噪点
for (int i = 0; i < 100; i++)
{
int x = rnd.Next(bmp.Width);
int y = rnd.Next(bmp.Height);
Color clr = color[rnd.Next(color.Length)];
bmp.SetPixel(x, y, clr);
}
//清除该页输出缓存,设置该页无缓存
context.Response.Buffer = true;
context.Response.ExpiresAbsolute = System.DateTime.Now.AddMilliseconds(0);
context.Response.Expires = 0;
context.Response.CacheControl = "no-cache";
context.Response.AppendHeader("Pragma", "No-Cache");
//将验证码图片写入内存流,并将其以 "image/Png" 格式输出
MemoryStream ms = new MemoryStream();
try
{
bmp.Save(ms, ImageFormat.Png);
context.Response.ClearContent();
context.Response.ContentType = "image/Png";
context.Response.BinaryWrite(ms.ToArray());
}
finally
{
//显式释放资源 bmp.Dispose();
g.Dispose();
}
}
 
public bool IsReusable
{
get
{
return false;
}
}
}
2.页面使用
<dl>
<dt>验 证 码:</dt>
<dd>
<input id="txtCode" name="txtCode" type="text" class="input code" placeholder="输入验证码" datatype="s4-20" nullmsg="请输入右边显示的验证码" sucmsg=" " />
<a class="send" title="点击切换验证码" href="javascript:;" onclick="ToggleCode(this, 'verify_code.ashx');return false;">
<img src="verify_code.ashx" width="80" height="22" />
</a>
</dd>
</dl>
3.切换验证码
//切换验证码
function ToggleCode(obj, codeurl) {
$(obj).children("img").eq(0).attr("src", codeurl + "?time=" + Math.random());
}
 4.MVC生成验证码
public class ValidateCode
{
public ValidateCode()
{
}
/// <summary>
/// 验证码的最大长度
/// </summary>
public int MaxLength
{
get { return 10; }
}
/// <summary>
/// 验证码的最小长度
/// </summary>
public int MinLength
{
get { return 1; }
}
/// <summary>
/// 生成验证码
/// </summary>
/// <param name="length">指定验证码的长度</param>
/// <returns></returns>
public string CreateValidateCode(int length,out string retInfo)
{
//int[] randMembers = new int[length];
//int[] validateNums = new int[length];
//string validateNumberStr = "";
////生成起始序列值
//int seekSeek = unchecked((int)DateTime.Now.Ticks);
//Random seekRand = new Random(seekSeek);
//int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000);
//int[] seeks = new int[length];
//for (int i = 0; i < length; i++)
//{
// beginSeek += 10000;
// seeks[i] = beginSeek;
//}
////生成随机数字
//for (int i = 0; i < length; i++)
//{
// Random rand = new Random(seeks[i]);
// int pownum = 1 * (int)Math.Pow(10, length);
// randMembers[i] = rand.Next(pownum, Int32.MaxValue);
//}
////抽取随机数字
//for (int i = 0; i < length; i++)
//{
// string numStr = randMembers[i].ToString();
// int numLength = numStr.Length;
// Random rand = new Random();
// int numPosition = rand.Next(0, numLength - 1);
// validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
//}
////生成验证码
//for (int i = 0; i < length; i++)
//{
// validateNumberStr += validateNums[i].ToString();
//}
//return validateNumberStr;
#region 字符数字随机
//StringBuilder sbcode = new StringBuilder();
//string strcode = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789";
 
//Random rand = new Random();
//for (int i = 0; i < length; i++)
//{
// sbcode.Append(strcode[rand.Next(0, strcode.Length)].ToString());
//}
//return sbcode.ToString(); #endregion
 
#region 验证码 +- 计算
string retcode="";
retInfo = "siweicn";
int seekSeek = unchecked((int)DateTime.Now.Ticks);
Random rand = new Random(seekSeek);
string stroper = "+*";
string oper = stroper[rand.Next(0, stroper.Length)].ToString();
string k1 = string.Empty;
string k2 = string.Empty;
 
switch (oper)
{
case "*":
{
k1 = rand.Next(1, 10).ToString();
k2 = rand.Next(1, 10).ToString();
retInfo = (int.Parse(k1) * int.Parse(k2)).ToString();
retcode = k1 + "* " + k2 + "=?";
break;
}
case "+":
{
k1 = rand.Next(1, 10).ToString();
k2 = rand.Next(1, 10).ToString();
retInfo = (int.Parse(k1) + int.Parse(k2)).ToString();
retcode = k1 + "+ " + k2 + "=?";
break;
}
}
return retcode;
#endregion
}
/// <summary>
/// 创建验证码的图片
/// </summary>
/// <param name="containsPage">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
public void CreateValidateGraphic(string validateCode)
{
//Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 13.0), 31);
Bitmap image = new Bitmap(82, 24);
Graphics g = Graphics.FromImage(image);
try
{
//生成随机生成器
Random random = new Random();
//清空图片背景色 g.Clear(Color.White);
//画图片的干扰线
for (int i = 0; i < 25; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(validateCode, font, brush, 0, 3);
//画图片的前景干扰点
for (int i = 0; i < 100; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
//画图片的边框线
g.DrawRectangle(new Pen(Color.Silver, 4), 0, 0, image.Width - 1, image.Height - 1);
//保存图片数据
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
 
//输出图片流 HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "image/jpeg";
HttpContext.Current.Response.BinaryWrite(stream.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
}
/// <summary>
/// 得到验证码图片的长度
/// </summary>
/// <param name="validateNumLength">验证码的长度</param>
/// <returns></returns>
public static int GetImageWidth(int validateNumLength)
{
return (int)(validateNumLength * 12.0);
}
/// <summary>
/// 得到验证码的高度
/// </summary>
/// <returns></returns>
public static double GetImageHeight()
{
return 22.5;
}
}
5.控制器中创建验证码
[AllowAnonymous]
[OutputCache(Location = OutputCacheLocation.None)]
public void VCode()
{
var code = new ValidateCode();
string retInfo;
var codeStr = code.CreateValidateCode(5, out retInfo);
Session["vcode"] = retInfo;
code.CreateValidateGraphic(codeStr);
}
6.view页面使用验证码
<li>
验证码:
<input id="code" type="text" name="vcode" placeholder="输入计算结果" />
<img id="vcode"
alt="验证码" title="点击刷新验证码" src="@Url.Action("VCode", "控制器名称")" />
</li>
7.点击刷新重置验证码
$("#vcode").click(function () {
var $this = $(this);
$this.attr("src", '@Url.Action("VCode", "控制器名称")?_=' + new Date().getTime());
})
 
 
<?php
//验证码类
class ValidateCode {
private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789';//随机因子
private $code;//验证码
private $codelen = 4;//验证码长度
private $width = 130;//宽度
private $height = 50;//高度
private $img;//图形资源句柄
private $font;//指定的字体
private $fontsize = 20;//指定字体大小
private $fontcolor;//指定字体颜色
//构造方法初始化
public function __construct() {
$this->font = dirname(__FILE__).'/font/elephant.ttf';//注意字体路径要写对,否则显示不了图片
}
//生成随机码
private function createCode() {
$_len = strlen($this->charset)-1;
for ($i=0;$i<$this->codelen;$i++) {
$this->code .= $this->charset[mt_rand(0,$_len)];
}
}
//生成背景
private function createBg() {
$this->img = imagecreatetruecolor($this->width, $this->height);
$color = imagecolorallocate($this->img, mt_rand(157,255), mt_rand(157,255), mt_rand(157,255));
imagefilledrectangle($this->img,0,$this->height,$this->width,0,$color);
}
//生成文字
private function createFont() {
$_x = $this->width / $this->codelen;
for ($i=0;$i<$this->codelen;$i++) {
$this->fontcolor = imagecolorallocate($this->img,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156));
imagettftext($this->img,$this->fontsize,mt_rand(-30,30),$_x*$i+mt_rand(1,5),$this->height / 1.4,$this->fontcolor,$this->font,$this->code[$i]);
}
}
//生成线条、雪花
private function createLine() {
//线条
for ($i=0;$i<6;$i++) {
$color = imagecolorallocate($this->img,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156));
imageline($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
//雪花
for ($i=0;$i<100;$i++) {
$color = imagecolorallocate($this->img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
imagestring($this->img,mt_rand(1,5),mt_rand(0,$this->width),mt_rand(0,$this->height),'*',$color);
}
}
//输出
private function outPut() {
header('Content-type:image/png');
imagepng($this->img);
imagedestroy($this->img);
}
//对外生成
public function doimg() {
$this->createBg();
$this->createCode();
$this->createLine();
$this->createFont();
$this->outPut();
}
//获取验证码
public function getCode() {
return strtolower($this->code);
}
}
?>
输出实例:
使用方法:
1、先把验证码类保存为一个名为 ValidateCode.class.php 的文件;
2、新建一个名为 captcha.php 的文件进行调用该类;
captcha.php
<?php
session_start();
require './ValidateCode.class.php'; //先把类包含进来,实际路径根据实际情况进行修改。
$_vc = new ValidateCode(); //实例化一个对象
$_vc->doimg();
$_SESSION['authnum_session'] = $_vc->getCode();//验证码保存到SESSION中
?>
3、引用到页面中,代码如下:
<img title="点击刷新" src="./captcha.php" align="absbottom" οnclick="this.src='captcha.php?'+Math.random();"></img>
4、一个完整的验证页面,代码如下:
 
<?php
<?php
session_start();
//在页首先要开启session,
//error_reporting(2047);
session_destroy();
//将session去掉,以每次都能取新的session值;
//用seesion 效果不错,也很方便
?>
<html>
<head>
<title>session 图片验证实例</title>
<style type="text/css">
#login p{
margin-top: 15px;
line-height: 20px;
font-size: 14px;
font-weight: bold;
}
#login img{
cursor:pointer;
}
form{
margin-left:20px;
}
</style>
</head>
<body>
<form id="login" action="" method="post">
<p>此例为session验证实例</p>
<p>
<span>验证码:</span>
<input type="text" name="validate" value="" size=10>
<img title="点击刷新" src="./captcha.php" align="absbottom" οnclick="this.src='captcha.php?'+Math.random();"></img>
</p>
<p>
<input type="submit">
</p>
</form>
<?php
//打印上一个session;
//echo "上一个session:<b>".$_SESSION["authnum_session"]."</b><br>";
$validate="";
if(isset($_POST["validate"])){
$validate=$_POST["validate"];
echo "您刚才输入的是:".$_POST["validate"]."<br>状态:";
if($validate!=$_SESSION["authnum_session"]){
//判断session值与用户输入的验证码是否一致;
echo "<font color=red>输入有误</font>";
}else{
echo "<font color=green>通过验证</font>";
}
}
?>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

 
 

推荐阅读