使用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页面通过链接获 ...
随机推荐
- C#调用C++的dll EntryPointNotFoundException
问题描述:不带参数的函数可以通过C#调用,含有参数的函数报错: EntryPointNotFoundException:此外,采用depends可以查看到所有导出函数. 此问题解决方案:步骤1:在C+ ...
- linux下打压缩解压
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
- springboot配置swagger
1,添加配置类 @Configuration @EnableSwagger2 @Profile({"default", "dev-online", " ...
- java中的编译时常量与运行时常量
常量是程序运行期间恒定不变的量,许多程序设计语言都有某种方式,向编译器告知一块数据是恒定不变的,例如C++中的const和Java中的final. 根据编译器的不同行为,常量又分为编译时常量和运行时常 ...
- python——获取文件列表
"""-------------------------------------------------------- <<获取文件列表>> () ...
- 从零开始学spring cloud(四) -------- 基础项目搭建
1.创建一个spring cloud项目 1.1.使用工具创建--idea 点击creat new project,选择spring initializr 点击next,选择下一步 填入自己的Grou ...
- IDEA中,将项目加入maven管理。
在项目上右键->Add Framework Support Choose Maven 生成pom.xml 在<project>下配置国内仓库 <properties>&l ...
- npm与cnpm的install无反应
问题描述 1.npm -v检查版本正常,npm install安装依赖提示超时 2.cnpm -v检查版本正常,cnpm install安装依赖无反应(输入命令后没有任何提示,一直卡在那) 解决(参考 ...
- eclipse Filter web.xml 问题解决 异步请求@WebServlet
<filter> <filter-name>AsynServlete</filter-name> <filter-class>com.kad.app.a ...
- js实现动态加载脚本的方法实例汇总
本文实例讲述了js实现动态加载脚本的方法.分享给大家供大家参考,具体如下: 最近公司的前端地图产品需要做一下模块划分,希望用户用到哪一块的功能再加载哪一块的模块,这样可以提高用户体验. 所以到处查 ...