完整验证码图片生成
验证码生成算法 -回复
验证码生成算法-回复
验证码生成算法是指用于验证用户身份的一种技术手段,通过生成一串随机的字符或数字,要求用户输入正确才能通过验证。随着网络技术的发展,验证码算法应用得越来越广泛,可以用于登录验证、注册账户、防止机器人恶意攻击等场景。本文将从生成原理、常见算法、安全性等方面一步一步介绍验证码生成算法。
一、生成原理
验证码生成算法的基本原理是通过生成随机的字符或数字,远程传递给客户端,并要求用户输入正确的验证码进行验证。这个过程一般包括以下几个步骤:
1. 生成随机字符或数字集合:首先需要确定验证码的内容,一般为字母、数字或字母数字组合。然后从这个集合中随机选择若干个字符或数字组成验证码。
2. 绘制验证码图片:将生成的验证码绘制到一张图片上,这样用户就需要通过观察图片中的字符或数字来输入正确的验证码。
3. 将验证码传递给客户端:通过网络传输将生成的验证码发送到客户端,一般是以图片的形式进行传递。
4. 用户输入验证:用户在登录或注册界面中看到验证码图片后,需要输入相应的验证码,系统则会对用户输入的验证码和生成的验证码进行比较,若输入正确则验证通过。
二、常见验证码生成算法
1. 普通随机算法:这是最直观的一种生成验证码的算法,即从字符或数字集合中随机选择若干个字符或数字组成验证码。这种算法简单易懂,但存在安全性较低的问题,因为生成的验证码很容易被机器人破解。
2. 扭曲算法:为了增加验证码的安全性,可以对生成的验证码进行扭曲处理,使得验证码不易被机器人自动识别。扭曲算法通常是通过对验证码图片进行一些形变操作,如扭曲、旋转、拉伸等,使得验证码不易被自动识别。
验证码大全
验证码
以下是目前主流验证码,如无特殊要求,请务必使用小写录入,切记不要使用大写!
xyxkkejwh gkghhzdx
以上验证码来自(全球最大交友网),7-10个字母,输入时间限制很很短(20秒左右),需要快速录入,否则无效!
rs4jr9g9 f5hqwp8r q53tgqcv
以上验证码来自,网站设定的输入时间限制较长,需要慢慢的准确输入。
lifolid
上图尤其要引起注意,这种类型的验证码是纯字母的,看到像数字7的一定是字母L,所以不要输错,毕竟打错是影响准确率的!
Cebus possession Hotchkiss 60-48s. $523.514 Linehan
此类验证码来自,需要区分大小写!即看到大写就录入大写,看到小写就小写录入!输入时两段码之间打一个空格。
比较繁琐的验证码,有空格,有"-",还有小数点"."和“$”等等符号。
3tx2x6u5 t3gtn8cs g6t5xhna
hotmail的验证码系列,主流码出码在TT LA BO里,固定的8个字符(字母加数字混合),输入时间限制很长,可以慢慢输入。
bbyume4h ny8bp4
(雅虎)的验证码系列(字母加数字混合),输入时间限制很较短,需要快速录入,所以容易吃码。
FCYVEA 4DZTDT EEV3EW
此种验证码比较少见,来自荷兰egv网,具体是否必须区分大小写,不得而知,可以首选大写录入!
rabresub miadocaill flystra frfajiv
这种类型的验证码是(谷歌)和其旗下(优兔贝视频站)的,红绿蓝三种颜色,东倒西歪,熟练了蛮好打的,小写输入。
生成验证码的几种方式
⽣成验证码的⼏种⽅式
⽣成验证码的⼏种⽅式1,在jsp页⾯中直接⽣成验证码
image.jsp源码:
//image.jsp
<%@ page contentType="image/jpeg"
import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"
pageEncoding="GBK"%>
<%!Color getRandColor(int fc, int bc) {//给定范围获得随机颜⾊
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}%>
<%
//设置页⾯不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
// 通过这⾥可以修改图⽚⼤⼩
int width = 85, height = 23;
SpringBoot实现前端验证码图片生成和校验
SpringBoot实现前端验证码图⽚⽣成和校验
SpringBoot下实现前端验证码图⽚的⽣成和校验,供⼤家参考,具体内容如下
1.效果
点击验证码可以获取新的验证码
2.原理
后台⽣成验证码图⽚,将图⽚传到前台。
后台在session中保存验证码内容。
前台输⼊验证码后传到后台在后台取出session中保存的验证码进⾏校验。
注意,验证码的明⽂是不能传送到前端的。前端内容都是透明的,不安全。验证码是⽤来防机器⼈并不是单单防⼈。如果把验证码明⽂传到前端很容易就会被破解。
3.图⽚⽣成
验证码⽣成⼯具类RandomValidateCodeUtil
public class RandomValidateCodeUtil {
public static final String RANDOMCODEKEY= "RANDOMVALIDATECODEKEY";//放到session中的key
private String randString = "0123456789";//随机产⽣只有数字的字符串 private String
//private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产⽣只有字母的字符串
//private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产⽣数字与字母组合的字符串
private int width = 95;// 图⽚宽
private int height = 25;// 图⽚⾼
验证码生成算法 -回复
验证码生成算法-回复
验证码生成算法是一种用于增加网络安全性的技术。它是一种用于验证用户身份或保护用户账户免受恶意活动的方法。验证码是一种数字、字母或符号的组合,由计算机生成并发送给用户,用户需要回答正确才能继续访问。
在本文中,我们将详细介绍验证码生成算法的原理、流程和几种常见的验证码类型。
一、验证码生成算法的原理
验证码生成算法的原理基于两个主要目标:可读性和唯一性。首先,验证码必须是易于识别的,以便用户能够正确回答验证问题。其次,每个验证码必须是唯一的,以防止恶意用户通过尝试不同的组合来猜测正确答案。
二、验证码生成算法的流程
验证码生成算法的流程可以总结为以下几个步骤:
1. 生成随机字符:算法首先生成一些随机字符,可以是数字、字母或符号的组合。这些字符的长度和类型可以根据实际需求进行调整。
2. 组合字符:算法将生成的随机字符按照一定规则进行组合,以生成验证码。这个规则可以是将字符按照一定的顺序排列,或者将字符打乱再组合。
3. 添加干扰元素:为了增加验证码的可读性和安全性,算法可能会在生成的验证码中添加一些干扰元素,如噪音、线条或扭曲效果。
4. 输出验证码:最后,算法将生成的验证码输出给需要验证的用户。这可以通过图片、音频或文本等形式进行。
三、常见的验证码类型
1. 图片验证码:这是最常见的验证码类型。它将生成的字符以图片的方式展示给用户,用户需要通过观察图片中的字符来回答验证问题。图片验证码往往有一定的干扰元素,例如噪音、颜色变化或扭曲效果,以增加安全性。
2. 短信验证码:这种验证码通过短信发送给用户,用户需要回答短信中的验证码问题才能继续操作。短信验证码通常是一组数字,长度可以根据需求设置。
验证码生成器
packagecom.lizhou.tools;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
import java.awt.Graphics2D;
importjava.awt.image.BufferedImage;
importjava.util.Random;
/**
* 验证码生成器
*
* @author bojiangzhou
*/
public class VCodeGenerator {
/**
* 验证码来源
*/
final private char[] code = {
'2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
/**
* 字体
*/
final private String[] fontNames = new String[]{
"黑体", "宋体", "Courier", "Arial",
"Verdana", "Times", "Tahoma", "Georgia"};
验证码生成器的使用方法
验证码生成器的使用方法
验证码生成器是一种用于生成验证码的程序,通常用于网站或应用程序中,以验证用户身份并防止恶意行为。以下是验证码生成器的一般使用方法:
1. 安装和配置:首先,您需要将验证码生成器添加到您的网站或应用程序中。这通常涉及将其代码库克隆到您的项目中,然后根据需要进行配置。这可能涉及设置验证码的尺寸、颜色、字体、背景等属性。
2. 调用生成器:在您的代码中,您需要调用验证码生成器来生成验证码。这通常涉及创建一个生成器实例,然后调用其生成方法。例如,您可以使用以下代码创建一个生成器实例并生成一个验证码:
```python
import captcha
captcha_generator = ()
captcha_()
```
3. 显示验证码:在您的网站或应用程序中,您需要将生成的验证码显示给用户。这通常涉及将验证码图像呈现给用户,例如将其嵌入到网页中。验证码
图像可以以多种方式呈现,例如通过在网页上显示一个图像标签或通过在前端JavaScript代码中动态生成图像。
4. 验证用户输入:当用户输入验证码时,您需要验证他们输入的字符是否与生成的验证码匹配。这通常涉及将用户输入与生成的验证码进行比较,以确认它们是否匹配。如果匹配,则用户输入有效;否则,用户输入无效,您需要要求他们重新输入验证码。
需要注意的是,具体的验证码生成器和用法可能因库和实现而异。因此,您应该查阅您所使用的特定库的文档以获取更详细的说明和用法示例。
java 图片验证码生成-免费版
1.Jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<%@ page contentType="text/html; charset=utf-8"%>
系统登录
rel="stylesheet" type="text/css">
action=""
method="post" name="login">
欢迎登录
用户:
tabindex="1"
style="font-family: '宋体'; font-size: 12px; color: #575757" />
密码:
style="font-family: '宋体'; font-size: 12px; color: #575757" />
验证码:
src="${pageContext.request.contextPath}/servlet/ImageServlet">
mce_href="javascript:reloadVerifyCode();">看不清楚
tabindex="3" value="确认" />
SpringBoot使用Captcha生成验证码
SpringBoot使用Captcha生成验证码验证码是一种用于验证用户身份的常见技术。使用验证码可以防止恶意用户自动注册、暴力破解密码、刷票等攻击。在Spring Boot中,我们可以使用Captcha库来生成验证码。
Captcha是一个Java库,用于生成图像验证码。它可以生成不同类型的验证码,包括数字、字母、算术运算符等。
首先,我们需要在项目的pom.xml文件中添加Captcha库的依赖:```xml
<dependency>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
```
然后,在Spring Boot的配置文件中添加以下配置:
```yaml
kaptcha:
border:
color: black
textproducer:
char.length: 4
image.width: 150
image.height: 50
```
这些配置可以根据需求进行调整。例如,可以更改验证码的字符集、长度、图像大小等。
接下来,在Spring Boot的控制器中添加生成验证码的方法:
```java
public void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException
//创建验证码生成器
DefaultKaptcha captchaProducer = new DefaultKaptcha(;
php生成图片验证码-附五种验证码
php⽣成图⽚验证码-附五种验证码
以前输出验证码的时候⽤过⼀个⽅法,在前台⽤JS⽣成验证码字符串,再传递到后台⽤PHP输出验证码图像。这样在验证时就不需要使⽤$_SESSION传递验证码
的值,直接⽤JS⽐较⽣成的字符串和输⼊的字符串是否相等即可。
本⽂以实例演⽰5种验证码,并介绍⽣成验证码的函数。PHP⽣成验证码的原理:通过GD库,⽣成⼀张带验证码的图⽚,并将验证码保存在Session中。
1、HTML
5中验证码HTML代码如下:
<div class="demo">
<h3>1、数字验证码</h3>
<p>验证码:<input type="text" class="input" id="code_num" name="code_num" maxlength="4" /> <img src="code_num.php" id="getcode_num" title="看不清,点击换⼀张" align="absmiddle" /></p> <p><input type="button" class="btn" id="chk_num" value="提交" /></p>
</div>
<div class="demo">
<h3>2、数字+字母验证码</h3>
<p>验证码:<input type="text" class="input" id="code_char" maxlength="4" /> <img src="code_char.php" id="getcode_char" title="看不清,点击换⼀张" align="absmiddle" /></p>
验证码生成方法
验证码生成方法
验证码生成方法主要包括以下几种:
1. 随机生成数字验证码:这是一种最简单的验证码生成方法,通过随机生成一串数字作为验证码,位数一般为4位或6位。
2. 随机生成字母和数字验证码:这种方法生成的验证码由大小写字母和数字组成,通常长度为6位。
3. 动态生成验证码:这种验证码生成方法需要用户进行一定的交互,例如点击或拖动鼠标等,以生成验证码。
4. 基于图像的验证码:这种验证码生成方法将随机生成的数字或字母嵌入到一张图片中,用户需要识别图片中的数字或字母才能完成验证。
5. 基于声音的验证码:这种验证码生成方法将随机生成的数字或字母转换成声音信号,用户需要通过听声音来识别验证码。
6. 动态短信验证码:这种验证码生成方法将随机生成的验证码发送到用户的手机或其他设备上,用户需要在规定时间内输入正确的验证码。
以上是几种常见的验证码生成方法,不同方法的适用场景和安全性也不同,可以根据实际需求选择适合的方法。
纯6位数字验证码(图片)
纯6位数字验证码(图⽚)<?php
//中⽂字符集
header('content-type:text/html;charset=utf-8');
//设置session,必须处于脚本最顶部
session_start();
//设置验证码图⽚⼤⼩的函数
$image = imagecreatetruecolor(600, 90);
//设置验证码颜⾊ imagecolorallocate(int im, int red, int green, int blue);
$bgcolor = imagecolorallocate($image,255,255,255);
//区域填充 int imagefill(int im, int x, int y, int col) (x,y) 所在的区域着⾊,col 表⽰欲涂上的颜⾊
imagefill($image, 0, 0, $bgcolor);
//设置变量
$captcha_code = "";
//⽣成随机数字6个
for($i=0;$i<6;$i++){
//设置字体⼤⼩
$fontsize = 10;
//设置字体颜⾊,随机颜⾊。0-120深颜⾊
$fontcolor = imagecolorallocate($image, rand(0,120),rand(0,120), rand(0,120));
//设置数字
$fontcontent = rand(0,9);
//=连续定义变量
$captcha_code .= $fontcontent;
//设置坐标
$x = ($i*100/6)+rand(5,15);
hutool-captcha的用法
hutool-captcha是一款Java开发工具,用于生成和验证验证码。它提供了丰富的API,可用于生成常见的验证码类型,如数字、字母、字母数字组合、算术表达式等。在本篇文章中,我们将介绍hutool-captcha的基本用法。
使用hutool-captcha生成验证码非常简单。首先,需要添加依赖到项目中。可通过在Maven的pom.xml文件中添加以下代码来完成:
```xml
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>5.7.8</version>
</dependency>
```
接下来,我们可以通过以下代码使用hutool-captcha生成验证码:
```java
// 创建验证码生成器
CaptchaUtil.createLineCaptcha(width, height);
// 设置验证码字符数
captcha.setLen(4);
// 设置干扰线的数量
captcha.setLineCount(100);
// 生成验证码图片
captcha.createCode();
// 获取验证码图片的Base64格式
captcha.getCaptchaBase64();
// 获取验证码的文本
captcha.getCode();
```
以上代码中,我们使用`CaptchaUtil.createLineCaptcha`方法创建了一个验证码生成器,并指定了验证码图片的宽度和高度。接着,我们可以通过`setLen`方法设置验证码的字符数,`setLineCount`方法设置干扰线的数量。然后,调用`createCode`方法生成验证码图片。通过`getCaptchaBase64`方法可以获取验证码图片的Base64格式,通过`getCode`方法可以获取验证码的文本。
java 验证码生成校验流程 -回复
java 验证码生成校验流程-回复
Java验证码生成校验流程
验证码是一种常用的用于验证用户身份或防止网络恶意攻击的方法。在Web应用程序中,常见的验证码有图片验证码,短信验证码等。本文将以Java为例,详细介绍验证码生成和校验的流程。
一、生成验证码
1. 首先,我们需要定义验证码的相关参数,如验证码的长度、宽度、高度、字体等信息。通常,这些参数会定义在一个配置文件中,以方便后续的调整和管理。
2. 在Java中,我们可以使用第三方库来生成验证码,如Google的Kaptcha、JCaptcha等。这些库提供了丰富的功能,可以生成验证码图片,并将验证码保存到session或redis等存储介质中。在本文中,我们选择使用Kaptcha作为示例。
3. 通过引入Kaptcha的依赖包,我们可以在代码中创建一个Kaptcha 对象,并设置相应的参数。例如,我们可以指定验证码的长度为4个字符,宽度为200像素,高度为50像素,字体为Arial,并设置字体大小和颜色等。
4. 调用Kaptcha的createText方法,生成一个随机的验证码字符串。该方法会根据指定的长度从一组预定义的字符中随机选择字符,并将其组合成一个字符串。
5. 接下来,我们可以调用Kaptcha的createImage方法,将验证码字符串转换成一个BufferedImage对象。然后,通过ImageIO的write
方法将BufferedImage对象以JPEG、PNG等格式保存为图片文件。同时,我们还可以将验证码字符串保存到session或redis中,以备后续的校验。
各类验证码的生成机制
各类验证码的生成机制
验证码是一种用于确认用户身份或防止机器人攻击的技术手段。不同
类型的验证码在生成机制上有所不同,下面将介绍几种常见的验证码生成
机制。
1.图片验证码:
图片验证码是最常见的验证码形式,它通常以一张包含数字、字母和
特殊字符的图片显示给用户,要求用户输入正确的验证码以证明自己是真
实用户。图片验证码的生成过程如下:
(1)选择验证码字符集合:生成图片验证码前,首先需要确定验证
码中所包含的字符集合,通常包括数字、字母和特殊字符。
(2)绘制验证码图像:从字符集合中随机选择一定数量的字符,并
在一个空白图像上进行随机位置的绘制,生成一个具有干扰项的图像。
(3)添加干扰项:为了防止机器识别验证码,还可以在图像中添加
一些噪声干扰,如随机的线条、点和曲线等。
(4)生成验证码:将绘制好的图像转换为二进制数据,并将结果返
回给用户。
2.数字验证码:
数字验证码是一种只包含数字的验证码形式,它的生成过程相对简单:(1)确定验证码位数:首先需要确定验证码中所包含的数字位数,
例如4位、6位等。
(2)生成随机数:根据位数要求,生成一组随机数字。
(3)返回验证码:将生成的随机数字返回给用户。
3.文字验证码:
文字验证码是一种只包含字母的验证码形式,它的生成过程类似于数
字验证码:
(1)确定验证码位数:确定验证码中所包含的字母位数。
(2)生成随机字母:根据位数要求,从一个字母集合中随机选择一
组字母。
(3)返回验证码:将生成的随机字母返回给用户。
4.点选验证码:
点选验证码是一种需要用户在图像中点击指定对象的验证码形式,它
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
?using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Web;
using Sd.Helper.Gif;
namespace VerifyCodeBase
{
///
/// 自定义生成校验码图片
///
public class VerifyCode
{
#region 构造函数
public VerifyCode()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
///
/// 指定图片高、宽的构造
/// 高和宽同时大于零时才生效
///
///
///
public VerifyCode(int h, int w)
{
if (h > 0 && w > 0)
{
_height = h;
_weight = w;
}
}
///
/// 指定图片高、宽,字体大小的构造
/// 高和宽同时大于零时才生效
///
///
///
///
public VerifyCode(int h, int w, int fontSize)
{
if (h > 0 && w > 0)
{
_height = h;
_weight = w;
}
if (fontSize > 0)
{
_fontSize = fontSize;
}
}
#endregion
private const double Pi = Math.PI;
private const double Pi2 = Math.PI * 2;
#region 字段
private string _code;
private Bitmap _imgmap;
private bool _isWave = true;
int _length = 4;
int _fontSize = 30;
private int _height = 60;
private int _weight = 150;
int _padding = 1;
int _noise = 30;
private int _noiseLine = 20;
private int _noiseLeve = 2;
Color _chaosColor = Color.LightGray;
Color _backgroundColor = Color.White;
Color[] _colors = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.DarkMagenta, Color.Brown, Color.DarkCyan, Color.Purple };
string[] _fonts = { "Gautami", "Tahoma", "宋体" };
string _codeSerial = "a,b,c,d,e,f,g,h,i,j,k,m,n,p,q,2,3,4,5,s,t,u,v,w,x,y,z,6,7,8,A,B,D,E,F,G,H,K,M,N,Q";
#endregion
#region 属性
///
/// 获取生成的验证码字符串
///
public string Code
{
get { return _code; }
}
///
/// 获取生成的验证码图片
///
Bitmap VerifyCodeImg
{
get
{
if (_imgmap == null)
{
_code = GetRadomStr.MakePassword(this.Length, PassChar.数字和大小写字母);
_imgmap = CreateImage(_code);
}
return _imgmap;
}
}
///
/// 验证码长度(默认4个验证码的长度)
///
public int Length
{
get { return _length; }
set { _length = value; }
}
///
/// 生成的图片高度
///
public int Heitht
{
get { return _length; }
set { _length = value; }
}
///
/// 是否对图片进行扭曲
///
public bool IsWave
{
get { return _isWave; }
set { _isWave = value; }
}
///
/// 生成的图片宽度
///
public int Weight
{
get { return _length; }
set { _length = value; }
}
///
/// 验证码字体大小默认30像素
///
public int FontSize
{
get { return _fontSize; }
set { _fontSize = value; }
}
///
/// 字符间距
///
public int Padding
{
get { return _padding; }
set { _padding = value; }
}
///
/// 燥音线数量
///
public int NoiseLine
{
get { return _noiseLine; }
set { _noiseLine = value; }
}
///
/// 燥音线干扰程度,数值越大,干扰越严重
///
public int NoiseLeve
{
get { return _noiseLeve; }
set
{
if(value <= 0) value = 1;
_noiseLeve = value;
}
}
///
/// 燥点数量、图片宽度的倍数
///
public int Noise
{
get { return _noise; }
set { _noise = value; }
}
///
/// 输出燥点的颜色(默认灰色)
///
public Color ChaosColor
{
get { return _chaosColor; }
set { _chaosColor = value; }
}
///
/// 自定义背景色(默认白色)
///
public Color BackgroundColor
{
get { return _backgroundColor; }
set { _backgroundColor = value; }
}
///
/// 自定义随机颜色数组
///
public Color[] Colors
{
get { return _colors; }
set { _colors = value; }
}
///
/// 自定义字体数组
///
public string[] Fonts
{
get { return _fonts; }
set { _fonts = value; }
}
///
/// 自定义随机码字符串序列(使用逗号分隔)
///
public string CodeSerial
{
get { return _codeSerial; }
set { _codeSerial = value; }
}
#endregion
#region 生成随机字符码
public string CreateVerifyCode(int codeLen)
{
if (codeLen == 0)
{
codeLen = Length;
}
string[] arr = CodeSerial.Split(',');
string code = "";
int temp = -1;
Random rand = new Random();
for (int i = 0; i < codeLen; i++)
{
if (temp != -1)
{
rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
}
int t = rand.Next(arr.Length - 1);
while (temp == t)
{
t = rand.Next(arr.Length - 1);
}
temp = t;
code += arr[t];
}
return code;
}
#endregion
#region 获得 BitmapData 指定坐标的颜色信息
///
/// 获得 BitmapData 指定坐标的颜色信息
///
/// 从图像数据获得颜色 必须为 PixelFormat.Format24bppRgb 格式图像数据
///
///
///
///
/// Format24BppRgb 已知X,Y坐标,像素第一个元素的位置为Scan0+(Y*Stride)+(X*3)。
/// 这是blue字节的位置,接下来的2个字节分别含有green、red数据。
///
private Color BitmapDataColorAt(BitmapData srcData, int x, int y)
{
byte[] rgbValues = new byte[3];
Marshal.Copy((IntPtr)((long)srcData.Scan0 + ((y * srcData.Stride) + (x * 3))), rgbValues, 0, 3);
return Color.FromArgb(rgbValues[2], rgbValues[1], rgbValues[0]);
}
#endregion
#region 设置 BitmapData 指定坐标的颜色信息
///
/// 设置 BitmapData 指定坐标的颜色信息
///
/// 设置图像数据的颜色 必须为 PixelFormat.Format24bppRgb 格式图像数据
///
///
/// 待设置颜色
///
/// Format24BppRgb 已知X,Y坐标,像素第一个元素的位置为Scan0+(Y*Stride)+(X*3)。
/// 这是blue字节的位置,接下来的2个字节分别含有green、red数据。
///
private void BitmapDataColorSet(Bitmap
Data destData, int x, int y, Color color)
{
byte[] rgbValues = new byte[3] { color.B, color.G, color.R };
Marshal.Copy(rgbValues, 0, (IntPtr)((long)destData.Scan0 + ((y * destData.Stride) + (x * 3))), 3);
}
#endregion
#region 波纹扭曲
///
/// 波纹扭曲
///
private Bitmap WaveDistortion(Bitmap bitmap)
{
Random rnd = new Random();
var width = bitmap.Width;
var height = bitmap.Height;
Bitmap destBmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
{
Color foreColor = Color.FromArgb(rnd.Next(10, 100), rnd.Next(10, 100), rnd.Next(10, 100));
Color backColor = Color.FromArgb(rnd.Next(200, 250), rnd.Next(200, 250), rnd.Next(200, 250));
using (Graphics g = Graphics.FromImage(destBmp))
{
g.Clear(backColor);
// periods 时间
double rand1 = rnd.Next(710000, 1200000) / 10000000.0;
double rand2 = rnd.Next(710000, 1200000) / 10000000.0;
double rand3 = rnd.Next(710000, 1200000) / 10000000.0;
double rand4 = rnd.Next(710000, 1200000) / 10000000.0;
// phases 相位
double rand5 = rnd.Next(0, 31415926) / 10000000.0;
double rand6 = rnd.Next(0, 31415926) / 10000000.0;
double rand7 = rnd.Next(0, 31415926) / 10000000.0;
double rand8 = rnd.Next(0, 31415926) / 10000000.0;
// amplitudes 振幅
double rand9 = rnd.Next(330, 420) / 110.0;
double rand10 = rnd.Next(330, 450) / 110.0;
double amplitudesFactor = rnd.Next(5, 6) / 12.0;//振幅小点防止出界
double center = width / 2.0;
//wave distortion 波纹扭曲
BitmapData destData = destBmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, destBmp.PixelFormat);
BitmapData srcData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
for (var x = 0; x < width; x++)
{
for (var y = 0; y < height; y++)
{
var sx = x + (Math.Sin(x * rand1 + rand5)
+ Math.Sin(y * rand2 + rand6)) * rand9 - width / 2 + center + 1;
var sy = y + (Math.Sin(x * rand3 + rand7)
+ Math.Sin(y * rand4 + rand8)) * rand10 * amplitudesFactor;
int color, color_x, color_y, color_xy;
Color overColor = Color.Empty;
if (sx < 0 || sy < 0 || sx >= width - 1 || sy >= height - 1)
{
continue;
}
else
{
color = BitmapDataColorAt(srcData, (int)sx, (int)sy).B;
color_x = BitmapDataColorAt(srcData, (int)(sx + 1), (int)sy).B;
color_y = BitmapDataColorAt(srcData, (int)sx, (int)(sy + 1)).B;
color_xy = BitmapDataColorAt(srcData, (int)(sx + 1), (int)(sy + 1)).B;
}
if (color == 255 && color_x == 255 && color_y == 255 && color_xy == 255)
{
continue;
}
else if (color == 0 && color_x == 0 && color_y == 0 && color_xy == 0)
{
overColor = Color.FromArgb(foreColor.R, foreColor.G, foreColor.B);
}
else
{
double frsx = sx - Math.Floor(sx);
double frsy = sy - Math.Floor(sy);
double frsx1 = 1 - frsx;
double frsy1 = 1 - frsy;
double newColor =
color * frsx1 * frsy1 +
color_x * frsx * frsy1 +
color_y * frsx1 * frsy +
color_xy * frsx * frsy;
if (newColor > 255) newColor = 255;
newColor = newColor / 255;
double newcolor0 = 1 - newColor;
int newred = Math.Min((int)(newcolor0 * foreColor.R + newColor * backColor.R), 255);
int newgreen = Math.Min((int)(newcolor0 * foreColor.G + newColor * backColor.G), 255);
int newblue = Math.Min((int)(newcolor0 * foreColor.B + newColor * backColor.B), 255);
overColor = Color.FromArgb(newred, newgreen, newblue);
}
BitmapDataColorSet(destData, x, y, overColor);
}
}
destBmp.UnlockBits(destData);
bitmap.UnlockBits(srcData);
}
if (bitmap != null)
bitmap.Dispose();
}
return destBmp;
}
#endregion
#region 产生波形滤镜效果
///
/// 正弦曲线Wave扭曲图片(Edit By )
///
///
name="srcBmp">图片路径
/// 如果扭曲则选择为True
/// 波形的幅度倍数,越大扭曲的程度越高,一般为3
/// 波形的起始相位,取值区间[0-2*PI)
///
public System.Drawing.Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
{
var destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
// 将位图背景填充为白色(防止扭曲后边角缺色)
var graph = System.Drawing.Graphics.FromImage(destBmp);
graph.Clear(BackgroundColor);
//graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), 0, 0, destBmp.Width, destBmp.Height);
graph.Dispose();
double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
for (int i = 0; i < destBmp.Width; i++)
{
for (int j = 0; j < destBmp.Height; j++)
{
double dx = 0;
dx = bXDir ? (Pi2 * (double)j) / dBaseAxisLen : (Pi2 * (double)i) / dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// 取得当前点的颜色
int nOldX = 0, nOldY = 0;
nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy * dMultValue);
System.Drawing.Color color = srcBmp.GetPixel(i, j);
if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height)
{
destBmp.SetPixel(nOldX, nOldY, color);
}
}
}
return destBmp;
}
#endregion
#region 创建GIF动画
///
/// 创建GIF动画
/// 不会覆盖VerifyCodeImg属性,创建的图像只能通过返回的 fullname 访问,请在访问后及时删除
///
/// 扩展名为".gif"的文件名,可包含目录名,为空时按日期自动生成
/// 返回文件的全名,包含物理路径
public void CreateImageGif(string filename, out string fullname)
{
AnimatedGifEncoder GifPic = new AnimatedGifEncoder();
Random rand = new Random();
filename = string.IsNullOrEmpty(filename) ? DateTime.Now.ToString("yyyyMMdd_HHmmssfff") + ".GIF" : filename;
fullname = pathHelper.getLocalPath(filename);
GifPic.Start(fullname);
//确保视觉残留
GifPic.SetDelay(3);
//-1:no repeat,0:always repeat
GifPic.SetRepeat(0);
for (int i = 0; i < 3;
i++)
{
int int1 = rand.Next(4, 12);
int int2 = rand.Next(1, 6);
bool _bool = int2 > 3;
var image = TwistImage(VerifyCodeImg, _bool, int1, int2);
GifPic.AddFrame(image);
}
GifPic.Finish();
}
#endregion
#region 图片生成方法
///
/// 图片生成方法,内部使用
///
/// 用于识别的字符串
///
private Bitmap CreateImage(string code)
{
int fSize = FontSize;
int fWidth = fSize + Padding;
var image = new System.Drawing.Bitmap(_weight, _height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(image);
g.Clear(BackgroundColor);
Random rand = new Random();
#region 画图片的背景噪音线
if (NoiseLine > 0)
{
for (int i = 0; i < NoiseLine; i++)
{
int x1 = rand.Next(image.Width);
int x2 = rand.Next(image.Width);
int y1 = rand.Next(image.Height);
int y2 = rand.Next(image.Height);
g.DrawLine(new Pen(Colors[rand.Next(Colors.Length - 1)], rand.Next(NoiseLeve)), x1, y1, x2, y2);
}
}
#endregion
#region 生成随机字体和颜色的验证码字符
int left, top, cindex, findex;
Font f;
Brush b;
for (int i = 0; i < code.Length; i++)
{
cindex = rand.Next(Colors.Length - 1);
findex = rand.Next(Fonts.Length - 1);
top = i % 2 == 0 ? 1 : 2;
left = i * fWidth;
f = new System.Drawing.Font(Fonts[findex], fSize, System.Drawing.FontStyle.Bold);
b = new System.Drawing.SolidBrush(Colors[cindex]);
g.DrawString(code.Substring(i, 1), f, b, left, top);
}
#endregion
#region 添加随机生成的燥点
if (Noise > 0)
{
//Pen pen = new Pen(ChaosColor, 0);
int c = Length * _noise;
for (int i = 0; i < c; i++)
{
int x = rand.Next(image.Width);
int y = rand.Next(image.Height);
g.DrawRectangle(new Pen(ChaosColor, rand.Next(NoiseLeve)), x, y, 1, 1);
}
}
#endregion
//渐变效果
//g.FillRectangle(new LinearGradientBrush(new Point(0, 0), new Point(image.Width, image.Height), Color.FromArgb(0, 0, 0, 0), Color.FromArgb(255, 255, 255, 255)), 0, 0, image.Width, image.Height);
//画一个边框边
框颜色为Color.Gainsboro
//g.DrawRectangle(new Pen(Color.Gainsboro, 0), 0, 0, image.Width - 1, image.Height - 1);
g.Dispose();
//波纹扭曲
if (IsWave)
{
//随机生成后三个参数(true or false,5~8,(0~2PI),)
int int1 = rand.Next(4, 12);
int int2 = rand.Next(1, 6);
bool _bool = int2 > 3;
image = TwistImage(image, _bool, int1, int2);
}
return image;
}
#endregion
#region 生成验证码图片
///
/// 生成验证码图片
///
/// 验证字符,为空则随机生成
/// 是否覆盖已生成的验证码图片,默认为覆盖
///
public Bitmap CreateImg(string code, bool covered = true)
{
if (string.IsNullOrEmpty(code))
{
code = GetRadomStr.MakePassword(this.Length, PassChar.数字和大小写字母);
}
if (covered)
{
_code = code;
_imgmap = CreateImage(_code);
return _imgmap;
}
return CreateImage(code);
}
#endregion
#region 获得图片数据的字节数组
///
/// 获得图片数据的字节数组
///
///
public byte[] GetImageData()
{
if (VerifyCodeImg != null)
{
var ms = new System.IO.MemoryStream();
VerifyCodeImg.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
}
return null;
}
#endregion
#region 将创建好的图片输出到页面
///
/// 将创建好的图片输出到页面
///
/// 用于输出的 HttpContext 实例
/// session 名称 默认为 CheckCode
public void CreateImageOnPage(HttpContext context, string sessionKey = "CheckCode")
{
context.Response.ClearContent();
context.Response.ContentType = "image/Jpeg";
context.Response.BinaryWrite(GetImageData());
if (!string.IsNullOrEmpty(sessionKey))
{
//如果没有实现IRequiresSessionState,则这里会出错,也无法生成图片
context.Session[sessionKey] = Code;
}
}
#endregion
}
}