使用kbmmw 实现图形验证码
首先感谢图形验证码的提供者 晴空无彩虹 https://blog.csdn.net/u011784006/article/details/80827181
他用FMX 实现了验证码的生成,我修改成了 VCL 版的。
整个生成验证码的单元,全程推出。
unit uVerifyCode; interface uses System.Classes, System.SysUtils,vcl.graphics,Vcl.ExtCtrls, System.IOUtils,
System.UIConsts, System.UITypes, kbmMWGlobal, jpeg,
System.Types;
// 本单元修改自 晴空无彩虹 的单元,表示感谢
type
// 生成验证码组件
TGenerateVerifyCode = class
private const
// 定义字典表,不要零(0),因为零和字母O样子太接近
arrStr: array [ .. ] of char = (
'','','','','','','','','',
'A','B','C','D','E','F','G','H','I',
'J','K','L','M','N','O','P','Q','R',
'S','T','U','V','W','X','Y','Z');
private
FBitmapWidth: integer; // 图片宽度
FBitmapHeight: integer; // 图片高度
FCodeCount: integer; // 取验证码字符的个数,默认是4个字符
FFontName: string; // 字体名称
FMinFontSize: integer; // 最小字体大小
FRandomLineCount: integer; // 背景随机线条数
FTransparency: byte; // 背景随机线条的透明度
FXRandomLen: integer; // X的随机值长度
FYRandomLen: integer; // Y的随机值长度
FLock:TkbmMWLock;
// 画出验证码函数
function VerifyCodeDrawImg(Img:TBitmap): string;
public
constructor Create();
destructor Destroy;override;
procedure GetVerifyCodeAndImage(ImageStream: TStream;
var VerifyCode: string); property Width: integer read FBitmapWidth write FBitmapWidth;
property Height: integer read FBitmapHeight write FBitmapHeight;
property CodeCount: integer read FCodeCount write FCodeCount;
property FontName: string read FFontName write FFontName;
property MinFontSize: integer read FMinFontSize write FMinFontSize;
property RandomLineCount: integer read FRandomLineCount
write FRandomLineCount;
property Transparency: byte read FTransparency write FTransparency;
property XRandomLen: integer read FXRandomLen write FXRandomLen;
property YRandomLen: integer read FYRandomLen write FYRandomLen;
end; function GetVerifyCodeAndImage( ImageStream: TStream):string; implementation function GetVerifyCodeAndImage( ImageStream: TStream):string;
var
gc:TGenerateVerifyCode;
begin
gc:=TGenerateVerifyCode.Create;
try
gc.GetVerifyCodeAndImage(ImageStream, result);
ImageStream.Position:=; finally
gc.Free;
end; end; constructor TGenerateVerifyCode.Create();
begin
inherited;
FBitmapWidth := ;
FBitmapHeight := ;
FCodeCount := ;
FFontName := '宋体';
FMinFontSize := ;
FRandomLineCount := ;
FTransparency := ;
FXRandomLen := ;
FYRandomLen := ;
FLock:=TkbmMWLock.Create; end; // 获取验证码和影像的流数据
destructor TGenerateVerifyCode.Destroy;
begin
FLock.Free;
inherited;
end; procedure TGenerateVerifyCode.GetVerifyCodeAndImage(ImageStream: TStream;
var VerifyCode: string);
var
Img: TBitmap;
jpg:TJPEGImage;
begin Img :=TBitmap.Create;
jpg:=TJPEGImage.Create;
try
Img.Width:=FBitmapWidth;
img.Height:=FBitmapHeight;
// 宽200,高60 VerifyCode := VerifyCodeDrawImg(Img);
jpg.Assign(img);
jpg.SaveToStream(ImageStream);
ImageStream.Position:=;
Img.SaveToStream(ImageStream); // 写到流中
finally freeandnil(Img);
freeandnil(jpg);
end; end; // 画出验证码函数
function TGenerateVerifyCode.VerifyCodeDrawImg(Img: TBitmap): string;
var
I, j, k: integer;
X, Y, W, H: integer;
vLeft: integer;
strResult,c,fn: String;
myrect:Trect;
begin
// 只取4个字符
fn:=Tpath.GetGUIDFileName;
For j := to FCodeCount do
begin
Randomize;
k := Random() mod ;
strResult := strResult + trim(arrStr[k]);
end; img.Canvas.Brush.Style:= bsSolid;
img.Canvas.Brush.Color:=AlphaColorToColor( MakeColor(Random() and $C0,Random() and $C0, Random() and $C0 , FTransparency));
img.Canvas.FillRect(TRect.Create(, ,FBitmapWidth, FBitmapHeight) ); sleep(); Img.Canvas.Font.Name := FFontName; for j := to FRandomLineCount do // 随机画100条线
begin
Randomize; Img.Canvas.Pen.Color :=AlphaColorToColor( MakeColor(Random() and $C0,Random() and $C0, Random() and $C0 , FTransparency));
Img.Canvas.Pen.Width:=; Img.Canvas.PenPos.SetLocation(Random(FBitmapWidth),Random(FBitmapHeight));
Img.Canvas.LineTo(Random(FBitmapWidth), Random(FBitmapHeight));
//
end; vLeft := ;
for I := to length(strResult) do
begin
Randomize;
// 字体大小
Img.Canvas.Font.Size := Random() + FMinFontSize;
// 随机字体颜色
Img.Canvas.Font.Color:= AlphaColorToColor( MakeColor(Random() and $C0,Random() and $C0, Random() and $C0 , FTransparency));
if Img.Canvas.Font.Size < (FMinFontSize + ) then
Img.Canvas.Font.Size := Img.Canvas.Font.Size +;
if Random() = then
Img.Canvas.Font.Style := [TFontStyle.fsBold]
else
Img.Canvas.Font.Style := [TFontStyle.fsItalic];
Img.Canvas.Font.Style:=Img.Canvas.Font.Style+[fsStrikeOut];
// 背景色反色
img.Canvas.Brush.Color:=Img.Canvas.Font.Color xor $FFFFFF;// AlphaColorToColor( MakeColor(Random(256) and $C0,Random(256) and $C0, Random(256) and $C0 , FTransparency));
Img.Canvas.Brush.Style:=bsSolid;
begin
X := Random(FXRandomLen) + vLeft;
Y := Random(FYRandomLen);
W := Img.Canvas.TextWidth(strResult[I])+;
H := Img.Canvas.TextHeight(strResult[I]);
myrect:=TRect.Create(X, Y, X + W, Y + H);
c:=strResult[i];
Img.Canvas.TextRect(myrect,c,[tfCenter] );
vLeft := X + W + ;
end;
end; for j := to do // 随机画5条线
begin
Randomize; Img.Canvas.Pen.Color :=AlphaColorToColor( MakeColor(Random() and $C0,Random() and $C0, Random() and $C0 , FTransparency));
Img.Canvas.Pen.Width:=; Img.Canvas.PenPos.SetLocation(Random(FBitmapWidth),Random(FBitmapHeight));
Img.Canvas.LineTo(Random(FBitmapWidth), Random(FBitmapHeight));
//
end; Result := strResult; // 返回值
end; end.
好了,我们下面在kbmmw 里面实现两个过程,一个过程是生成随机验证图片,并保存验证码在内存中。另外一个过程就是
验证浏览器输入的验证码。本篇文章主要是讨论功能实现,请大家在实际应用中进一步完善,保证信息和数据安全。
[kbmMW_Rest('method:get, path:"getvimage", responseMimeType:"image/jpeg"')]
[kbmMW_Method]
function Getvimage:TkbmMWBytes;
var
vcodelist:TkbmMWThreadDictionary<string,string>;
function TkbmMWCustomHTTPSmartService1.Getvimage: TkbmMWBytes;
var
imgs,js:Tmemorystream;
vcode:string;
hlp,reshlp:TkbmMWRESTTransportStreamHelper;
cookie:TkbmMWHTTPCookie;
stoken:string;
begin
hlp:=TkbmMWRESTTransportStreamHelper(RequestTransportStream.Helper);
imgs:=Tmemorystream.create;
try
vcode:=GetVerifyCodeAndImage(imgs);
Result:=TkbmMWPlatformMarshal.Stream2Bytes(imgs);
stoken:=THashmd5.GetHashString(TkbmMWMixerPasswordGen.Make);
cookie:=TkbmMWHTTPCookie.Create;
cookie.Name:='vcode';
cookie.Value:=stoken;
cookie.Expires:=Tkbmmwdatetime.Null;
reshlp:=TkbmMWRESTTransportStreamHelper(ResponseTransportStream.Helper);
reshlp.Cookies.Add(cookie);
vcodelist.Add(stoken,vcode); finally
imgs.free; end; end;
[kbmMW_Rest('method:post, path:"vcodetest", responseMimeType:"text/html"')]
[kbmMW_Method]
function vcodetest:string;
function TkbmMWCustomHTTPSmartService1.vcodetest: string;
var
hlp:TkbmMWRESTTransportStreamHelper;
vl:TkbmMWHTTPCustomValues;
m,invcode,vcode:string;
p:Tbytes;
begin result:='验证失败!'; hlp:=TkbmMWRESTTransportStreamHelper(RequestTransportStream.Helper); m:= hlp.Cookies.ValueByName['vcode']; if m='' then exit; vl:=TkbmMWHTTPQueryValues.Create;
try p:= RequestStream.SaveToBytes; vl.AsString:= Tencoding.ASCII.GetString(p); invcode:= vl.ValueByName['vcode']; if not vcodelist.TryGetValue(m,vcode) then
vcode:=''; finally
vl.Free end; if invcode=vcode then
result:='验证通过!'; end;
新建一个HTML 文件 叫 vcodetest.html
<script type="text/javascript" src="/xalionrest/scripts/jquery-1.12.4.min.js"></script>
<script language="javascript" >
$().ready(function(){
$("#img-code").bind( 'click', function () {
$(this).attr('src','/xalionrest/getvimage?t='+Math.random());
}); $("#form1").submit(function(){ if ($("input[name='vcode']").val() == ""){ alert("验证码不能为空!"); $("input[name='vcode']").focus(); return false }
}); });
</script>
<form name="form1" id="form1" method="post" action="/xalionrest/vcodetest" enctype="application/x-www-form-urlencoded" >
<tr>
<td align="center">
<span class="style2">输入验证码</span><input name="vcode" type="text" id="vcode">
<img src="/xalionrest/getvimage" height=60 width=200 id="img-code" class="Verify-Code" style="cursor:pointer" alt="验证码" title="看不清楚?请刷新"> </td>
</tr> <tr> <td align="center">
<br>
<input type="submit" name="Submit" value="提交" >
<input type="reset" name="Submit" value="重置">
</td>
</tr>
</form>
运行。
浏览器里面输入 http://127.0.0.1/xalionrest/vcodetest.html
输入验证吗,点提交。
大年初二,祝大家在猪年,万事如意,大吉大利!
2019.5.18 update :使用了kbmmw 5.09中新加的 TkbmMWThreadDictionary<string,string> 处理 键值,效果更好,更方便。
使用kbmmw 实现图形验证码的更多相关文章
- 【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...
- C#生成图形验证码
先看效果: 再上代码 public class CaptchaHelper { private static Random rand = new Random(); private static in ...
- php 图形验证码的3种方法
生成图形验证码需要使用php GD库来生成,如果你没开户GD库我们需要在php.ini文件找到extension=php_gd2.dll 去掉前面的;就行了,然后重启apache 或iis环境即可 检 ...
- PHP5 GD库生成图形验证码(汉字)
PHP5 GD库生成图形验证码且带有汉字的实例分享. 1,利用GD库函数生成图片,并在图片上写指定字符imagecreatetruecolor 新建一个真彩色图像imagecolorallocate ...
- ASP.NET中如何生成图形验证码
通常生成一个图形验证码主要 有3个步骤: (1)随机产生一个长度为N的随机字符串,N的值可由开发可由开发人员自行设置.该字符串可以包含数字.字母等. (2)将随机生成的字符串创建成图片,并显示. (3 ...
- PHP5生成图形验证码(有汉字)
利用PHP5中GD库生成图形验证码 类似于下面这样 1.利用GD库函数生成图片,并在图片上写指定字符 imagecreatetruecolor 新建一个真彩色图像 imagecolora ...
- [ASP.NET] 图形验证码破解-以简单图形为例
原文 http://www.dotblogs.com.tw/joysdw12/archive/2013/06/08/captcha-cracked.aspx 前言 这次来讲个比较有趣的主题,就是该如何 ...
- Net Core 生成图形验证码
1. NetCore ZKweb 在我第一次绘制图形验证码时是采用的ZKweb的绘制库,奉上代码参考 public byte[] GetVerifyCode(out string ...
- Tornado框架实现图形验证码功能
图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...
随机推荐
- yml使用
yml: value: 可以用单引号或者双引号引起来,这样就不会出现内容中特殊字符含义. yml中 key:value ,如果value是数字需要和前面的冒号隔一个空格,否则获取不到value
- Servlet学习记录3
提交表单信息 Web程序的任务是实现服务器与客户端浏览器之间的信息交互.客户端提交的信息可能来自表单里的文本框,密码框,选择框,单选按钮,复选框以及文件域.这些表单信息被以参数形式提交到了服务器.Se ...
- UE4 Virtual Reality Input输入配置表导入
[/Script/Engine.InputSettings] AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton2",Axi ...
- ModelSerializer Meta设置
class AccountSerializer(serializers.ModelSerializer): class Meta: # 模型名称 model = User # 序列化返回的字段 fie ...
- BackgroundWorker 组件 -- 进度条
代码: BackgroundWorker bw = new BackgroundWorker(); public MainWindow() { InitializeComponent(); bw.Wo ...
- 【笔记】Python基础七:正则表达式re模块
一,介绍 正则表达式(RE)是一种小型的,高度专业化的编程语言,在python中它内嵌在python中,并通过re模块实现.正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行. 字符匹配 ...
- 手游开发之lua的class函数详解
众所周知,lua没有类这个概念但其通过table实现了面向对象的“类”.在cocos2dx引擎下提供了class(className, ...)函数方法名,因为在脚本开发中这个接口基本都会用来创建一个 ...
- py_innodb_page_info
python py_innodb_page_info.py -v /usr/local/var/mysql/ibdata1 mylib.py #encoding=utf-8 import os imp ...
- OSPFv3综合实验(GNS3)
一.实验目的 1. 掌握 OSPFv3(v2) 的配置方法 2. 掌握在帧中继环境下 OSPFv3 (v2)的配置方法 3. 掌握 OSPFv3(v2) NSSA 的配置方法 4. 掌握外部路 ...
- css fixed 失效问题解法
https://stackoverflow.com/questions/11258877/fixed-element-disappears-in-chrome 开启css硬件加速,transform: ...