首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 生成隨機中文漢字驗證碼:原理與實現

     編輯:關於C語言

背景與動機

傳統數字/字母驗證碼易被 OCR 識別,騰訊等大廠曾採用中文漢字驗證碼提升安全性。本文詳細解析基於 GB2312 區位碼隨機生成常用漢字的原理,並提供完整控制台示例代碼。

核心原理:GB2312 區位碼結構

GB2312-80 將漢字編排在 94 個區、每區 94 位,共 8836 個碼位,其中一級漢字 3755 個(按拼音排序)、二級漢字 3008 個(按部首/筆畫排序)。

  • 區碼:0xA1–0xFE (161–254),對應 1–94 區
  • 位碼:0xA1–0xFE,對應 1–94 位
  • 實際字節 = 區碼+0x80, 位碼+0x80(即高位置 1)

例如「好」字區位碼 26區35位 → 區碼 0xB0+25=0xC9? 實際查表為 0xBA 0xC3(原文示例)。

可用漢字範圍篩選

並非所有碼位均為常用漢字,需排除:

  1. 第 1–15 區 (0xA1–0xAF) 多為符號、日文假名
  2. 第 16 區 (0xB0) 起始為一級漢字
  3. 第 55 區 (0xD7) 之後多為罕見二級漢字
  4. 每區第 1 位 (0xA0) 和第 94 位 (0xFE) 通常空碼

因此隨機範圍限定為:

  • 高位字節:0xB0–0xD6 (第 16–54 區)
  • 低位字節:0xA1–0xFE,但首尾各排除 1 個
  • 特殊處理 0xD7 區:低位字節 ≤ 0xF6

.NET 實現關鍵點

Encoding.GetEncoding("gb2312")

獲取 GB2312 編碼器,核心方法:

  • GetBytes(string):字符串 → 字節數組
  • GetString(byte[]):字節數組 → 字符串

隨機生成合法雙字節


public static byte[] GenerateValidGb2312Char(Random rnd)
{
    // 高字節:0xB0(176) 到 0xD6(214)
    int high = rnd.Next(0xB0, 0xD7); // [176, 214]
    
    int low;
    if (high == 0xD7) // 第 55 區特殊處理
        low = rnd.Next(0xA1, 0xF7); // 0xA1-0xF6
    else
        low = rnd.Next(0xA1, 0xFF); // 0xA1-0xFE
    
    // 排除每區首尾空碼 (簡化處理)
    if (low == 0xA1 || low == 0xFE) low = 0xA2;
    
    return new byte[] { (byte)high, (byte)low };
}

完整控制台程序


using System;
using System.Text;

class ChineseCaptcha
{
    static Random rnd = new Random();
    
    static void Main()
    {
        Encoding gb = Encoding.GetEncoding("gb2312");
        int count = 4;
        string captcha = "";
        
        for (int i = 0; i < count; i++)
        {
            byte[] bytes = GenerateValidGb2312Char(rnd);
            string ch = gb.GetString(bytes);
            // 過濾掉可能生成的控制字符或亂碼
            if (IsValidHanzi(ch)) 
                captcha += ch;
            else 
                i--; // 重試
        }
        
        Console.WriteLine($"生成驗證碼: {captcha}");
        // 後續可用 GDI+ 繪製干擾線、扭曲、噪點生成圖片
    }
    
    static bool IsValidHanzi(string s)
    {
        // 簡單判斷:是否為 CJK 統一表意文字基本區塊
        foreach (char c in s)
            if (c < 0x4E00 || c > 0x9FFF) return false;
        return true;
    }
    
    static byte[] GenerateValidGb2312Char(Random rnd) { /* 同上 */ }
}

從驗證碼到圖片:GDI+ 繪製要點

  1. 創建 Bitmap、Graphics,設置 SmoothingMode、TextRenderingHint
  2. 隨機字體、字號、顏色、旋轉角度
  3. 繪製干擾線:DrawLine、DrawCurve(貝塞爾曲線)
  4. 添加噪點:隨機 FillRectangle 1x1 像素
  5. 輸出 image/png 或保存文件

現代項目的更好選擇

  • ASP.NET Core:使用 Microsoft.AspNetCore.Antiforgery + 前端圖形驗證碼庫 (如 captcha-com)
  • 行為驗證:Google reCAPTCHA v3、Geetest、阿里云驗證碼,無感知、安全性更高
  • 純前端 Canvas:減輕後端壓力,配合簽名驗證防繞過

總結

理解 GB2312 區位碼結構是生成中文驗證碼的關鍵。通過限定高低字節範圍、過濾空碼,配合 Encoding.GetString 解碼,即可獲得常用漢字。實際部署時務必結合圖形干擾、會話綁定、限流等措施,或直接採用成熟的行為驗證服務。

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