首先感谢图形验证码的提供者  晴空无彩虹  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 实现图形验证码的更多相关文章

  1. 【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...

  2. C#生成图形验证码

    先看效果: 再上代码 public class CaptchaHelper { private static Random rand = new Random(); private static in ...

  3. php 图形验证码的3种方法

    生成图形验证码需要使用php GD库来生成,如果你没开户GD库我们需要在php.ini文件找到extension=php_gd2.dll 去掉前面的;就行了,然后重启apache 或iis环境即可 检 ...

  4. PHP5 GD库生成图形验证码(汉字)

    PHP5 GD库生成图形验证码且带有汉字的实例分享. 1,利用GD库函数生成图片,并在图片上写指定字符imagecreatetruecolor 新建一个真彩色图像imagecolorallocate ...

  5. ASP.NET中如何生成图形验证码

    通常生成一个图形验证码主要 有3个步骤: (1)随机产生一个长度为N的随机字符串,N的值可由开发可由开发人员自行设置.该字符串可以包含数字.字母等. (2)将随机生成的字符串创建成图片,并显示. (3 ...

  6. PHP5生成图形验证码(有汉字)

    利用PHP5中GD库生成图形验证码 类似于下面这样 1.利用GD库函数生成图片,并在图片上写指定字符 imagecreatetruecolor   新建一个真彩色图像      imagecolora ...

  7. [ASP.NET] 图形验证码破解-以简单图形为例

    原文 http://www.dotblogs.com.tw/joysdw12/archive/2013/06/08/captcha-cracked.aspx 前言 这次来讲个比较有趣的主题,就是该如何 ...

  8. Net Core 生成图形验证码

    1. NetCore ZKweb       在我第一次绘制图形验证码时是采用的ZKweb的绘制库,奉上代码参考      public byte[] GetVerifyCode(out string ...

  9. Tornado框架实现图形验证码功能

    图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...

随机推荐

  1. pycharm+Django+MySQL项目连接数据库中原有数据库

    1.安装驱动 一般会有MySQLdb.pymysql等,因为python版本等问题,我安装的是pymysql. 还可以在项目里安装,File->settings->project 2.在项 ...

  2. 【EFM32】EFM32芯片解锁、加锁操作

    [解锁] 使用J-Flash,新建Project,选择对应的EFM32芯片型号. 选择Target >> Connect >> Unsecure chip ,便进行解锁了,解锁 ...

  3. 一个socket数量的问题

    最近遇到一个问题,从业务上出现ftp异常: ftp .**.**.** ftp: connect: Cannot assign requested address 这台服务器上的socket统计如下: ...

  4. (转)Thinkpad X1 Carbon 扩展硬盘

    http://tieba.baidu.com/p/5837920925 网上看到有人成功利用X1C空闲的4G模块来实现了扩充用的是东芝RC100或者建兴的T11 其实难点应该是2242这种尺寸的SSD ...

  5. openstack使用openvswitch实现vxlan的方法

    openstack使用openvswitch实现vxlan,分享给大家,具体如下: openstack环境: 1 版本:ocata 2 系统:ubuntu16.04.2 3 控制节点 1个 + 计算节 ...

  6. C# webapi简单学习

    创建WebApi项目: 在VS工具中创建一个ASP.NET Web应用程序 选择Webapi 一个webapi项目就创建好了 这里简单的写一个post和get两种请求的方法,由于post请求参数需要参 ...

  7. aop原理及理解

    概念 Aspect Oriented Programming,面向切面编程,实际上它是一个规范.一种设计思路,总之是抽象的. 先上图 使用目的 从项目结构上来说 对业务逻辑的各个部分进行隔离,降低业务 ...

  8. BackgroundWorker 组件

    代码: static void Main(string[] args) { BackgroundWorker bw = new BackgroundWorker(); bw.WorkerReports ...

  9. 18. 4Sum (JAVA)

    Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums s ...

  10. c# int类型的转datetime类型

    int a =20190319; DateTime  b =  DateTime.ParseExact(a.tostring(),"yyyyMMdd",System.Globali ...