验证码生成器

生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符。

unit AuthenticodeGenerate;

interface

uses
  SysUtils, Windows, ExtCtrls, Graphics;

function GenerateAuthenticode(const Img: TImage; const Len: Integer = 4): string;

implementation

const
  cCharDigitArrayLen = 6;
  cCharDigitArray      : array[0..cCharDigitArrayLen - 1] of Char = (‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘);

  cCharLowerLetterArrayLen = 13;
  cCharLowerLetterArray: array[0..cCharLowerLetterArrayLen - 1] of Char = (‘b‘, ‘c‘, ‘e‘, ‘h‘, ‘j‘, ‘k‘, ‘m‘, ‘n‘, ‘s‘, ‘t‘, ‘v‘, ‘w‘, ‘y‘);

  cCharUpperLetterArrayLen = 19;
  cCharUpperLetterArray: array[0..cCharUpperLetterArrayLen - 1] of Char = (‘A‘, ‘B‘, ‘C‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘, ‘J‘, ‘K‘, ‘L‘, ‘M‘, ‘N‘, ‘P‘, ‘Q‘, ‘R‘, ‘S‘, ‘V‘, ‘W‘, ‘Y‘);

  cArrayTypeNum = 3;

  cFontNameNum = 5;
  cFontNameArray: array[0..cFontNameNum - 1] of string = (‘Arial‘, ‘Tahoma‘, ‘宋体‘, ‘幼圆‘, ‘微软雅黑‘);

function TwistImage(const SrcBmp: TBitmap; XDir: Boolean; MultFactor: Double; Phase: Double; SinTrick: Boolean): TBitmap;
const
  cTwicePi = 6.283185;
var
  BaseAxisLen : Double;
  I, J        : Integer;
  DestX, DestY: Double;
  OldX, OldY  : Integer;
  Color       : TColor;
begin
  Result := TBitmap.Create;
  Result.SetSize(SrcBmp.Width, SrcBmp.Height);

  if XDir then
    BaseAxisLen := Result.Height
  else
    BaseAxisLen := Result.Width;

  for I := 0 to Result.Width - 1 do
  begin
    for J := 0 to Result.Height - 1 do
    begin
      if XDir then
        DestX := (cTwicePi * J) / BaseAxisLen
      else
        DestX := (cTwicePi * I) / BaseAxisLen;

      if SinTrick then
      begin
        DestX := DestX + Phase;
        DestY := Sin(DestX);
      end else
      begin
        DestX := DestX + Phase;
        DestY := Cos(DestX);
      end;

      if XDir then
      begin
        OldX := I + Round(DestY * MultFactor);
        OldY := J;
      end else
      begin
        OldX := I;
        OldY := J + Round(DestY * MultFactor);
      end;

      Color := SrcBmp.Canvas.Pixels[I, J];
      if (OldX >= 0) and (OldX < Result.Width) and (OldY >= 0) and (OldY < Result.Height) then
        Result.Canvas.Pixels[OldX, OldY] := Color;
    end;
  end;
end;

procedure NoiseImage(const Img: TImage);
const
  cNoiseLineNum  = 5;
  cNoisePointNum = 50;
var
  I: Integer;
  X: Integer;
  Y: Integer;
begin
  for I := 0 to cNoiseLineNum - 1 do
  begin
    Img.Canvas.Pen.Style := psSolid;

    case Random(3) of
      0: Img.Canvas.Pen.Color := clBlack;
      1: Img.Canvas.Pen.Color := clGray;
    else
      Img.Canvas.Pen.Color := clSilver;
    end;

    X := Random(Img.Width);
    Y := Random(Img.Height);
    Img.Canvas.MoveTo(X, Y);
    Img.Canvas.LineTo(X + Random(Img.Width - X), Y + Random(Img.Height - Y));
  end;

  for I := 0 to cNoisePointNum - 1 do
  begin
    case Random(3) of
      0: Img.Canvas.Pixels[Random(Img.Width), Random(Img.Height)] := clBlack;
      1: Img.Canvas.Pixels[Random(Img.Width), Random(Img.Height)] := clGray;
    else
      Img.Canvas.Pixels[Random(Img.Width), Random(Img.Height)] := clSilver;
    end;
  end;
end;

function GenerateCharacterAuthenticode(const Img: TImage; const Len: Integer = 4): string;
var
  I: Integer;
  V: Char;
  X: Integer;
  Y: Integer;
  L: Integer;
begin
  Result := ‘‘;

  for I := 0 to Len - 1 do
  begin
    case Random(cArrayTypeNum) of
      0:
        begin
          V := cCharDigitArray[Random(cCharDigitArrayLen)];
          Result := Result + V;
        end;
      1:
        begin
          V := cCharLowerLetterArray[Random(cCharLowerLetterArrayLen)];
          Result := Result + V;
        end;
    else
        begin
          V := cCharUpperLetterArray[Random(cCharUpperLetterArrayLen)];
          Result := Result + V;
        end;
    end;
  end;

  L := 2 + Random(2);
  Img.Picture := nil;

  for I := 0 to Length(Result) - 1 do
  begin
    Img.Canvas.Font.Size := Random(5) + 17;
    Img.Canvas.Font.Color := RGB(Random(256) and $C0, Random(256) and $C0, Random(256) and $C0);
    case Random(3) of
      0: Img.Canvas.Font.Style := [fsBold];
      1: Img.Canvas.Font.Style := [fsItalic];
    end;
    Img.Canvas.Font.Name := cFontNameArray[Random(cFontNameNum)];
    X := Random(4) + L;
    Y := Random(2) + 4;
    Img.Canvas.TextOut(X, Y, Result[I + 1]);
    L := X + Img.Canvas.TextWidth(Result[I + 1]) + Random(2);
  end;

  if Random(2) = 0 then
  begin
    if Random(2) = 0 then
      Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, True, 8 + Random(3), 1 + Random(2), True)
    else
      Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, False, 8 + Random(3), 1 + Random(2), True);
  end else
  begin
    if Random(2) = 0 then
      Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, True, 8 + Random(3), 1 + Random(2), False)
    else
      Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, False, 8 + Random(3), 1 + Random(2), False);
  end;

  NoiseImage(Img);
end;

function GenerateAuthenticode(const Img: TImage; const Len: Integer): string;
begin
  Result := GenerateCharacterAuthenticode(Img, Len);
end;

initialization
  Randomize;

end.

调用很简单:

uses
  AuthenticodeGenerate;

procedure TfrmMain.btnTestClick(Sender: TObject);
begin
  lbl1.Caption := GenerateAuthenticode(img1);
end;

于是就有:

注:

1)、为减少识别难度,去掉了几个不易识别的字符如 1、I 等;

2)、验证码背景色当然也可以(应该)随机。

时间: 2024-10-16 00:18:28

验证码生成器的相关文章

JavaUtil_04_验证码生成器

一.原理 验证码其实就是随机串.原理上可分为两种: 1.简单的验证码 直接通过字母和数字的ASCII码生成.本文采用的验证码就是这种. 2.复杂的验证码 通过一个随机串,一个指定串(如accesskey),和当前时间来进行验证码的生成,期间还经过SHA1加密.如网易云信的短信验证码生成器: CheckSumBuilder.java package com.ray.im.util; import java.security.MessageDigest; /**@desc : 验证码生成工具 * *

验证码生成器(在TImage.Canvas上写字,很好看)

生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符. unit AuthenticodeGenerate; interface uses SysUtils, Windows, ExtCtrls, Graphics; function GenerateAuthenticode(const Img: TImage; const Len: Integer = 4): string; implementation const cCharDigitArrayLen = 6

0914作业-----改进后的验证码生成器---生成4-8位可重复验证码

1 import java.util.Scanner; 2 import java.util.Random; 3 public class Text1 4 { 5 public static void main(String[] args) 6 { 7 Code code=new Code(); 8 code.start(); 9 } 10 } 11 class Code 12 { 13 char[] range=new char[62]; //定义验证码取值范围的数组 14 char[] co

自己封装的一个java图片验证码

验证码生成器: 1 package com.lz.Tools; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.Graphics2D; 7 import java.awt.image.BufferedImage; 8 import java.util.Random; 9 10 /** 11 * 验证码生成器 12 * 13 * @author boji

生成验证码效果

生成验证码效果    ValidateCode.java 验证码生成类 Java代码   package cn.dsna.util.images; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; impor

javaweb之验证码

看了尚硅谷佟刚老师讲的httpsession应用中的验证码,总觉得一遍又一遍的写这些东西实在没意思,所有就简单封装了一个验证码生成器,默认支持纯数字.纯字母.数字字母组合.简单的10以内的加减乘的验证码. 先声明:代码中BufferedImage等的生成部分和一些对验证码的修饰都是来自佟刚老师的代码! 下载jar包: http://files.cnblogs.com/huyongliang/codeGenerator.zip 来个截图: 一 结构概览 CheckCode类是这个工具包的抽象父类,

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(三)给Shiro登录验证加上验证码

序: 给Shiro加入验证码,有多种方式,当然你也可以通过继承修改FormAuthenticationFilter类,通过Shiro去验证验证码.具体实现请百度: 应用Shiro到Web Application(验证码实现) 而今天我要说的,既然使用的SpringMVC,为什么不直接在Controller中就处理验证码验证,让事情变的更简单一点呢? 一.新建ValidateCode.java验证码工具类 package org.shiro.demo.util; import java.util.

基于python语言的tensorflow的‘端到端’的字符型验证码识别源码整理(github源码分享)

基于python语言的tensorflow的‘端到端’的字符型验证码识别 1   Abstract 验证码(CAPTCHA)的诞生本身是为了自动区分 自然人 和 机器人 的一套公开方法, 但是近几年的人工智能技术的发展,传统的字符验证已经形同虚设. 所以,大家一方面研究和学习此代码时,另外一方面也要警惕自己的互联网系统的web安全问题. Keywords: 人工智能,Python,字符验证码,CAPTCHA,识别,tensorflow,CNN,深度学习 2   Introduction 全自动区

Jsp+servlet 验证码案例

昨晚在csdn看到一位前辈写一个ajax+servlet+jsp验证.顿时心血来潮,在阅读前辈的代码下我亲手体验一下,做了一个验证码生成工具类.以供大家做个參考. 1:加入VeriyCodeUtils类生成验证码图像 package com.servlet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import jav