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

C# 實作 QQ 驗證碼辨識(OCR):特徵庫比對法完整原始碼解析

     編輯:關於C語言

前言

本文分析一套針對 QQ 早期驗證碼(49×20 像素、4 字元)的辨識系統,採用像素特徵向量比對法:將字元二值化後,按行計算黑色像素位模式組成 20 維向量,與預建特徵庫比對,差異行數 < 4 視為匹配。程式碼包含特徵庫建立、序列化存取、字元切割與辨識完整流程。

核心資料結構

// 特徵庫容量:100,000 筆
public static int DataCount = 0;
public static ushort[,] FeatureVectors = new ushort[100000, 20]; // 每筆 20 行特徵
public static byte[,] CharSize = new byte[100000, 2];            // 寬、高
public static byte[] CharLabels = new byte[100000];              // 對應字元 (ASCII)

// 待辨識暫存
public ushort[] CurrentVector = new ushort[20];
public byte CurrentWidth, CurrentHeight;

關鍵演算法流程

1. 二值化與字元切割

  • 亮度 < 0.999 視為前景(黑)。
  • 水平投影尋找字元邊界:連續有前景像素的欄位區間。
  • 垂直投影裁剪上下邊界,取得有效區域。
  • 寬度 > 16 像素視為噪聲/黏連,捨棄。

2. 特徵向量產生(行位模式)

// 每行 16 位元對應 16 欄像素,LSB 對應左邊
ushort[] bitMask = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 };

for (int row = y1; row <= y2; row++)
{
    ushort pattern = 0;
    for (int col = x1; col < x2; col++)
        if (binary[col, row]) pattern |= bitMask[col - x1];
    CurrentVector[row - y1] = pattern;
}

3. 特徵庫比對

public string MatchCharacter()
{
    for (int i = 0; i < DataCount; i++)
    {
        if (CharSize[i, 0] != CurrentWidth || CharSize[i, 1] != CurrentHeight) continue;

        int diffRows = 0;
        for (int r = 0; r < 20; r++)
            if (FeatureVectors[i, r] != CurrentVector[r]) diffRows++;

        if (diffRows < 4) // 容差閾值
            return ((char)CharLabels[i]).ToString();
    }
    return "";
}

4. 特徵庫序列化(二進位格式)

欄位長度說明
筆數4 bytes (int, Big-Endian)
每筆特徵20 × 2 bytes (ushort, Big-Endian)20 行向量
寬度1 byte
高度1 byte
字元標籤1 byteASCII code

完整類別架構

namespace QQ
{
    public class CaptchaRecognizer
    {
        public CaptchaRecognizer(Bitmap captchaImage) { _image = captcha; }

        // 靜態工具方法:int/ushort ↔ byte[] (Big-Endian)
        public static void IntToBytes(int val, byte[] buf) { ... }
        public static void UShortToBytes(ushort val, byte[] buf) { ... }
        public static int BytesToInt(byte[] buf) { ... }
        public static ushort BytesToUShort(byte[] buf) { ... }

        // 特徵庫持久化
        public static void SaveLibrary(string path) { ... }
        public static void LoadLibrary(string path) { ... }

        // 核心流程
        public void ExtractFeatures() { /* 切割 + 向量化 + 加入庫(標籤=空白) */ }
        public string Recognize() { /* 切割 + 向量化 + 比對拼接 */ }

        // 私有輔助
        private bool ExistsInLibrary() { ... }
        private void AddToLibrary() { ... }
    }
}

效能與準確率分析

限制與改進方向

  • 固定尺寸假設:僅支援 49×20、4 字元、等寬切割,通用性低。
  • 簡單閾值二值化:對雜訊、干擾線、字元黏連抗性弱。
  • 特徵向量維度固定:高度固定 20 行,字元縮放會失效。
  • 改進建議:
    • 引入投影切割 + 連通元件分析處理黏連字元。
    • 使用關鍵點特徵(SIFT/ORB 簡化版)或 CNN 深度學習模型。
    • 採用動態時間規整 (DTW) 處理字元寬度變化。
    • 特徵庫採用 KD-Tree 或 LSH 加速最近鄰搜尋。

法律與道德提醒

驗證碼辨識技術僅供學術研究與安全測試使用。繞過驗證碼進行自動化註冊、爬蟲濫用、暴力破解等行為可能違反《電腦犯罪條例》或網站服務條款,請遵守法律法規與機器人協議 (robots.txt)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
指標數值/說明
單字元比對時間~100,000 × 20 次整數比較 ≈ 2M 操作,現代 CPU < 5ms
辨識率特徵庫 8 萬+ 筆可達 80%+,15 萬筆可更高
記憶體佔用約 100,000 × (40+2+1) ≈ 4.3 MB
多執行緒適合度高(純邏輯運算、無共享寫入)