首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Delphi 實現驗證碼功能:核心思路與關鍵技術點完整指南

     編輯:程式設計綜合問答

需求背景

Delphi 開發登錄界面,需生成圖形驗證碼(含干擾線、噪點、字符旋轉、顏色隨機),防止自動化腳本暴力破解。

核心生成流程(最佳回答精華版)

  1. 字符池準備:排除易混淆字符 (0/O, 1/I/l, 8/B 等),定義 const Chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'。
  2. 畫布初始化:創建 TBitmap,設定寬高 (如 120x40),背景填充隨機淺色或漸變。
  3. 逐字符繪製:
    • 隨機字體 (Font.Name/Size/Style/Color),顏色排除白色/背景色。
    • TextOut 繪制到臨時 TBitmap (單字符畫布)。
    • 隨機旋轉角度 (±15°~±30°),使用 Rotate (需自行實現或用 PlgBlt/SetWorldTransform + XFORM 矩陣)。
    • 將旋轉後字符 CopyRect/Draw 到主驗證碼圖片,X 位置遞增並加隨機偏移。
  4. 添加干擾元素:
    • 隨機直線 (2-4 條):Canvas.MoveTo/LineTo,隨機顏色/寬度/虛線樣式。
    • 隨機貝塞爾曲線 (1-2 條):增加機器識別難度。
    • 噪點 (50-200 個):Canvas.Pixels[X,Y] := RandomColor 或填充隨機小矩形。
  5. 輸出與驗證:
    • 將生成的驗證碼字符串存入 Session (Web) 或全局變量/數據庫 (C/S),設置過期時間 (如 5 分鐘)。
    • 圖片輸出:Bitmap.SaveToStream → JPEG/PNG 流 → HTTP 響應 / TImage.Picture 顯示。
    • 用戶輸入提交時,大小寫不敏感比對,驗證成功銷毀 Session 防重放。

關鍵技術點代碼片段

1. 字符旋轉 (Windows GDI SetWorldTransform)

uses Graphics, Math, Windows;

procedure DrawRotatedText(Canvas: TCanvas; const S: string; X, Y: Integer; Angle: Double; FontColor: TColor);
var
  XForm: TXForm;
  OldMode: Integer;
  LogFont: TLogFont;
begin
  Canvas.Font.Color := FontColor;
  GetObject(Canvas.Font.Handle, SizeOf(LogFont), @LogFont);
  LogFont.lfEscapement := Round(Angle * 10);  // 0.1 度單位
  LogFont.lfOrientation := LogFont.lfEscapement;
  Canvas.Font.Handle := CreateFontIndirect(LogFont);
  
  OldMode := SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
  try
    Canvas.TextOut(X, Y, S);
  finally
    SetGraphicsMode(Canvas.Handle, OldMode);
    // 恢復字體
  end;
end;

2. 干擾線與噪點

procedure AddNoise(Canvas: TCanvas; Width, Height: Integer);
var
  i: Integer;
begin
  // 干擾線
  Canvas.Pen.Width := Random(2) + 1;
  for i := 1 to Random(3) + 2 do begin
    Canvas.Pen.Color := RandomColor;
    Canvas.Pen.Style := TPenStyle(Random(3)); // psSolid, psDash, psDot
    Canvas.MoveTo(Random(Width), Random(Height));
    Canvas.LineTo(Random(Width), Random(Height));
  end;
  // 噪點
  for i := 1 to Random(100) + 50 do
    Canvas.Pixels[Random(Width), Random(Height)] := RandomColor;
end;

function RandomColor: TColor;
begin
  Result := RGB(Random(200), Random(200), Random(200)); // 避免純白/純黑
end;

3. 完整生成函數骨架

function GenerateCaptcha(var Code: string; Width, Height: Integer): TBitmap;
const
  CharSet = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
var
  Bmp, CharBmp: TBitmap;
  i, CharCount, XPos: Integer;
  Ch: Char;
  Angle: Double;
begin
  Code := '';
  CharCount := 4 + Random(2); // 4-5 位
  Bmp := TBitmap.Create;
  try
    Bmp.Width := Width;
    Bmp.Height := Height;
    Bmp.PixelFormat := pf24bit;
    // 背景
    Bmp.Canvas.Brush.Color := RGB(230 + Random(25), 230 + Random(25), 230 + Random(25));
    Bmp.Canvas.FillRect(Rect(0, 0, Width, Height));
    
    XPos := 10;
    for i := 1 to CharCount do begin
      Ch := CharSet[Random(Length(CharSet)) + 1];
      Code := Code + Ch;
      
      CharBmp := TBitmap.Create;
      try
        CharBmp.Width := 30;
        CharBmp.Height := Height;
        CharBmp.Canvas.Brush.Style := bsClear;
        CharBmp.Canvas.Font.Size := 20 + Random(6);
        CharBmp.Canvas.Font.Style := [fsBold];
        CharBmp.Canvas.Font.Color := RandomColor;
        CharBmp.Canvas.TextOut(0, 0, Ch);
        
        Angle := (Random(60) - 30) * Pi / 180; // -30°~+30°
        // 這裡需用 PlgBlt 或 SetWorldTransform 旋轉 CharBmp 到 Bmp
        // 簡化示意:直接 TextOut + 旋轉字體 (見上方 DrawRotatedText)
        DrawRotatedText(Bmp.Canvas, Ch, XPos, 5, Angle * 180 / Pi, RandomColor);
      finally
        CharBmp.Free;
      end;
      XPos := XPos + 22 + Random(8); // 字符間距
    end;
    
    AddNoise(Bmp.Canvas, Width, Height);
    Result := Bmp;
  except
    Bmp.Free;
    raise;
  end;
end;

安全性增強建議

  • 服務端驗證:驗證邏輯必須在服務端,客戶端僅做提示。
  • 限制嘗試次數:IP/用戶/設備維度,超限鎖定 15-30 分鐘。
  • 防重放:驗證碼一次性使用,驗證成功即銷毀。
  • 無障礙備選:提供語音驗證碼按鈕 (TTS 讀出)。
  • 現代替代方案:考慮集成 reCAPTCHA v3 / hCaptcha / GeeTest 等成熟服務,前端幾行 JS,後端驗證 Token,省去圖片生成維護成本。

結語

Delphi 生成驗證碼核心在於:字符隨機化 + 幾何變換(旋轉/扭曲) + 干擾元素疊加 + 服務端強驗證。上述代碼框架可直接集成到 VCL/FMX 項目,配合 TIdHTTPServer (Indy) 或 WebBroker 輸出圖片流。若項目允許,強烈建議接入成熟驗證碼服務,安全性與維護性雙贏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved