node識別驗證碼

瞭解驗證碼

什麼是驗證碼?

所謂驗證碼,就是將一串隨機產生的數字或符號,生成一幅圖片,圖片里加上一些干擾象素(防止OCR),由用戶肉眼識別其中的驗證碼信息,輸入表單提交網站驗證,驗證成功後才能使用某項功能,通俗說就是一種區分用戶是計算機和人的公共全自動程序

驗證碼的做用

能夠防止惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定註冊用戶用特定程序暴力破解方式進行不斷的登錄嘗試,所使用驗證碼技術是如今不少網站通行的方式(好比招商銀行的網上我的銀行,百度社區)。
沒有驗證碼登錄,黑客會更加容易破解你的帳號,經過組合碼刷機等黑客技術來破取你的密碼,有了驗證碼至關於加了一層很厚的屏障,安全係數很高。

常見的驗證碼

  1. 隨機的四位數字的組合,這是最原始的驗證碼
  2. 隨機數字圖片驗證碼,圖片上的字符比較中規中矩,驗證做用比上一個好
  3. 隨機數字+隨機大小寫英文字母圖片驗證碼,每刷新一次,每一個字符還會變位置
  4. 隨機數字+隨機大小寫英文字母+隨機干擾像素+隨機位置圖片驗證碼,比上一個驗證做用更好,不易識別

如何識別驗證碼的內容?

所須要的工具:node

Tesseract

識別工具,目前由Google維護,支持中文,默認的識別率很低,特別是中文,可是能夠本身提供樣本,訓練提升識別率。

安裝:git

brew install tesseract --all-languages // MAC安裝
npm install node-tesseract // // windows安裝

在DOS窗口輸入:tesseract,顯示如圖則證實安裝成功github

ZULBRNUK%7BBU$3%5BY~0JM0%7BGB.png

命令行使用方法:npm

tesseract imagename outputbase [-l lang] [-psm pagesegmode] [configfile…]

imagename爲目標圖片文件名,需加格式後綴;outputbase是轉換結果文件名;lang是語言名稱(在Tesseract-OCR中tessdata文件夾可看到以eng開頭的語言文件eng.traineddata),如不標-l eng則默認爲eng;pagesegmode則是生成結果顯示相關配置。json

例如:windows

tesseract 1.jpg result -psm 7 

tesseract code.jpg result -l chi_sim -psm 7 //  -l chi_sim 表示用簡體中文字庫, -psm 7 表示告訴tesseract code.jpg圖片是一行文本,這個參數能夠減小識別錯誤率,默認爲3

node使用方法(官方示例):安全

var tesseract = require('node-tesseract');

// Recognize text of any language in any format
tesseract.process(__dirname + '/path/to/image.jpg',function(err, text) {
    if(err) {
        console.error(err);
    } else {
        console.log(text);
    }
});

// Recognize German text in a single uniform block of text and set the binary path

var options = {
    l: 'deu',
    psm: 6,
    binary: '/usr/local/bin/tesseract'
};

tesseract.process(__dirname + '/path/to/image.jpg', options, function(err, text) {
    if(err) {
        console.error(err);
    } else {
        console.log(text);
    }
});

運行結果:app

圖片描述圖片描述

圖片描述圖片描述

嘗試調用此方法後會在本地文件生成一個對應的txt文件,內容即爲識別內容。能夠看出來,對於簡單清楚的驗證碼識別還比較準確,可是對於帶有噪點或者其餘影響的識別效果的就很坑,徹底識別不出來,因此咱們須要對圖片進行一些處理,好比提升圖片的閾值,好比設置爲55%,能夠用ps等軟件實現,可是node中已經有相應的包graphicsmagick,能夠對圖像進行這種處理,比較方便。async

graphicsmagick


很是實用的圖像處理工具,通常後臺想要處理圖片就須要下載 graphicsmagick,能夠方便實現好比:製做縮略圖、頭像剪切等功能。
驗證碼的識別成功率跟圖片質量關係密切,通常拿到後的驗證碼都得通過灰度化,二值化,去噪,利用graphicsmagick就能夠很方便的作到。

安裝:工具

brew install imagemagick
brew install graphicsmagick // Mac安裝

npm install gm // windows安裝

命令行使用方法:

gm convert 1.jpg -thumbnail "100x100!" output_1.jpg  // 非等比縮圖,生成的圖片大小是:100x100

gm convert 1.jpg 1.pdf  // 格式轉換

node使用方法(官方示例):

var fs = require('fs')
  , gm = require('gm');

// resize and remove EXIF profile data
gm('/path/to/my/img.jpg')
.resize(240, 240)
.noProfile()
.write('/path/to/resize.png', function (err) {
  if (!err) console.log('done');
});

// some files would not be resized appropriately
// http://stackoverflow.com/questions/5870466/imagemagick-incorrect-dimensions
// you have two options:
// use the '!' flag to ignore aspect ratio
gm('/path/to/my/img.jpg')
.resize(240, 240, '!')
.write('/path/to/resize.png', function (err) {
  if (!err) console.log('done');
});

運行結果:
圖片描述圖片描述圖片描述

能夠看出,gm成功將這個圖片進行裁剪或者轉換爲pdf格式,使用很方便。

使用node識別驗證碼示例

新建項目目錄

在合適的磁盤目錄下建立項目目錄 node-orc

初始化項目

1.進入 node-orc文件夾下
2.執行 npm init,初始化 package.json文件

安裝依賴包

1. npm install gm
2. npm install node-tesseract

新建index.js,寫入代碼以下:

var fs        = require('fs');
var tesseract = require('node-tesseract');
var gm        = require('gm');

/**
 * 對圖片進行閾值處理(默認55)
 */
function disposeImg (imgPath, newPath, thresholdValue) {
  return new Promise((resolve, reject) => {
    gm(imgPath)
      .threshold(thresholdValue || 55)
      .write(newPath, (err)=> {
        if (err) return reject(err);
        resolve(newPath);
      });
  });
}

/**
 * 識別閾值化後圖片內容
 */
function recognizeImg (imgPath, options) {
  options = Object.assign({psm: 8}, options);
  // options = Object.assign({l: 'chi_sim'}, options); // 識別中文

  return new Promise((resolve, reject) => {
    tesseract
      .process(imgPath, options, (err, text) => {
        if (err) return reject(err);
        resolve(text.replace(/[\r\n\s]/gm, '')); // 去掉識別結果中的換行回車空格
      });
  });
}

async function recognize(imgPath, newPath, thresholdValue) {
  try {
    const newImgPath = await disposeImg(imgPath, newPath, thresholdValue)
    const result = await recognizeImg(newImgPath)
    console.log(`識別結果:${result}`)
  } catch (err) {
    console.error(`識別失敗:${err}`);
  }
}

recognize('1.jpg', 'test_1.jpg')

運行代碼

進入當前目錄,運行 node index便可直接打印出當前識別的結果

識別結果
圖片描述圖片描述

圖片描述圖片描述

圖片描述圖片描述

能夠看到比以前的識別率高不少,可是仍是細節方便識別不夠好,不夠完善,感興趣的能夠看看tesseract訓練,訓練一個本身的識別庫,精確度會提升不少

注意:
windows直接運行代碼會提示Could not execute GraphicsMagick/ImageMagick: gm "convert",這是由於Windows系統找不到gm中的convert命令,因此須要咱們安裝個客戶端工具GraphicsMagick(下載的時候要下載Q8版本的),而後,由於convert這個命令執行須要特定的環境,因此咱們須要在電腦的環境變量中加gm.exe的所在目錄

關於中文的識別

目前這個庫只能識別英文,中文直接是亂碼,如何識別中文呢?
咱們能夠下載一箇中文庫,下載地址以下: https://pan.baidu.com/s/13DCN...,並下載 Tesseract-OCR安裝包, tesseract安裝目錄的 tessdata文件是存放語言庫的,能夠將解壓後的文件放入這個文件夾下,字庫文件擴展名爲. raineddata 簡體中文字庫文件名爲 chi_sim.traineddata,使用的時候帶上語言類型便可,例如: tesseract 7.jpg result -l chi_sim

中文識別效果:

圖片描述圖片描述

最後總結

  1. 對於簡單的驗證碼直接用Tesseract識別
  2. 對於一些有噪點或者其餘影響的驗證碼能夠經過graphicsmagick進行圖像處理,再用Tesseract識別
  3. 關於中文或者其餘語言的識別須要單獨下載相關的語言庫並放到tessData文件夾下,並在Tesseract識別代碼中配置一下

整個識別效果仍是不夠完善,想要識別結果的準確度更高,能夠對代碼進行Tesseract訓練,由於這個稍微複雜點,以後會繼續瞭解,但願你們多多交流指正!

相關代碼

本文相關代碼和圖片github地址: https://github.com/fighting12...
相關文章
相關標籤/搜索