基於 CNN 的驗證碼破解實戰

2022-01-12 Python中文社區


作者:沂水寒城,CSDN博客專家,個人研究方向:機器學習、深度學習、NLP、CV

Blog: http://yishuihancheng.blog.csdn.net

在我們的實際生活中有很多的場景需要輸入驗證碼,在工程實踐中為了將數據採集、模擬登錄等一系列操作行為自動化處理就需要處理好驗證碼的識別工作,已有的工作中基於機器學習和深度學習都有很多的工作開展出來,效果也都不錯,今天本文的主要內容就是基於卷積神經網絡CNN模型來構建驗證碼圖片識別模型。

整體流程示意圖如下圖所示:

其中,主要的工作分為三個部分:數據採集、數據預處理和模型構建與測試。上述是之前一個實際完成的項目流程示意圖,本文主要是實踐基於CNN來構建識別模型,對於數據採集和預處理部分不作為講解的內容,感興趣可以親身實踐一下,都是圖像處理領域內的比較基礎的內容。

經過處理後我們將原始的驗證碼圖片均進行了基本的去噪、二值化以及歸一化等處理得到了可用於模型直接訓練使用的特徵向量數據,原始的驗證碼圖像數據如下所示:

處理後生成的特徵向量文件如下所示:

上圖中,每一行表示一個字符子圖,每一列表示字符子圖的一維數據,向量的維數就是經過歸一化處理後的字符子圖【寬x高】的值,即:將二維的矩陣數據轉化為了一維的向量數據,這一步不是必須的,只是我這裡採用了這種處理方式。

生成得到原始驗證碼圖片數據的特徵向量後就可以搭建訓練模型了,具體的代碼實現如下所示:

keys = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','N','P','Q','R','S','T','U','V','X','Y','Z']



def trainModel(feature='data.csv',batch_size=128,nepochs=50,ES=False,n_classes=31,model_path='vcModel.h5'):
    '''
    模型訓練
    '''
    df = pd.read_csv(feature)
    vals = range(31)
    label_dict = dict(zip(keys, vals))
    x_data = df[['v'+str(i+1) for i in range(320)]]
    y_data = pd.DataFrame({'label':df['label']})
    y_data['class'] = y_data['label'].apply(lambda x: label_dict[x])
    #數據集劃分
    X_train, X_test, Y_train, Y_test = train_test_split(x_data, y_data['class'], test_size=0.3, random_state=42)
    x_train = np.array(X_train).reshape((1167, 20, 16, 1))
    x_test = np.array(X_test).reshape((501, 20, 16, 1))
    # label編碼處理
    y_train = np_utils.to_categorical(Y_train, n_classes)
    y_val = np_utils.to_categorical(Y_test, n_classes)
    input_shape = x_train[0].shape
    #CNN模型搭建開始  【可以根據自己的實際情況進行增刪和調整】
    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3, 3), input_shape=input_shape, padding='same'))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
    model.add(Dropout(0.4))
    model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
    model.add(Dropout(0.4))
    model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
    model.add(Dropout(0.4))
    model.add(Flatten())
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(128, activation='relu'))
    model.add(Dense(n_classes, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    plot_model(model, to_file='vcModel.png', show_shapes=True)
    if ES:
        callbacks = [EarlyStopping(monitor='val_acc', patience=10, verbose=1)]  #提前終止策略
        history = model.fit(x_train, y_train, batch_size=batch_size, epochs=nepochs, \
                            verbose=1, validation_data=(x_test, y_val), callbacks=callbacks)
    else:
        history = model.fit(x_train, y_train, batch_size=batch_size, epochs=nepochs, verbose=1, validation_data=(x_test, y_val))
    model.save(model_path)
    #模型準確度、損失函數曲線繪製
    plt.clf()
    plt.plot(history.history['acc'])
    plt.plot(history.history['val_acc'])
    plt.title('Model Accuracy')
    plt.ylabel('Accuracy')
    plt.xlabel('Epochs')
    plt.legend(['train','test'], loc='upper left')
    plt.savefig('train_validation_acc.png')
    plt.clf()
    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('Model Loss')
    plt.ylabel('Loss')
    plt.xlabel('Epochs')
    plt.legend(['train', 'test'], loc='upper left')
    plt.savefig('train_validation_loss.png')




if __name__=='__main__':
    trainModel(feature='data.csv',batch_size=128,nepochs=100,ES=False,n_classes=31,model_path='vcModel.h5')

默認設置了100次的迭代,不開啟提前終止策略,訓練完成後截圖如下所示:

訓練完成後就得到了離線的識別模型文件,可重複加載使用,我們在訓練結束後繪製了模型的準確度和損失值對比曲線,如下所示:

從準確度和損失值對比曲線綜合來看可以發現:模型在20次迭代計算後就趨近於平穩,之後保持一個比較穩定的狀態。

之後對模型的識別能力進行測試分析,測試代碼實現如下:

def predict(pic_path,pdir='test_verifycode/chars/',saveDir='test_verifycode/predict/'):
    '''
    預測識別
    '''
    pic_list = os.listdir(pdir)
    if pic_list:
        for File in pic_list:
            os.remove(pdir+ File)
    splitImage(pic_path)
    pic_list = os.listdir(pdir)
    if pic_list:
        for File in pic_list:
            remove_edge_picture(pdir+ File)
        for File in os.listdir(pdir):
            resplit(pdir+ File)
        for File in os.listdir(pdir):
            picConvert(pdir, File)
        pic_list = sorted(os.listdir(pdir), key=lambda x: x[0])
        table = np.array([loadImage(pdir, File) for File in pic_list]).reshape(-1,20,16,1) 
        cnn = load_model('vcModel.h5')
        y_pred = cnn.predict(table)
        predictions = np.argmax(y_pred, axis=1)
        keys = range(31)
        vals = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z']
        label_dict = dict(zip(keys, vals))
        predict_label=''.join([label_dict[pred] for pred in predictions])
        moveFile(pdir,saveDir+predict_label+'/')
        return predict_label


def mainFunc(picDir='VerifyCode/'):
    '''
    主模塊
    '''
    count=0
    pic_list=os.listdir(picDir)
    total=len(pic_list)
    for one_pic in pic_list:
        true_label=one_pic.split('.')[0].strip()
        one_pic_path=picDir+one_pic
        predict_label=predict(one_pic_path)
        print('True Label: {0}, Predict Label: {1}.'.format(true_label,predict_label))
        if true_label==predict_label:
            count+=1
    print('Accuracy: ',count/total)

測試結果截圖如下所示:

使用了200張的驗證碼測試集來測試模型的識別能力,最終的準確度為87%,感覺還是不錯的,畢竟我只使用了不到2000的訓練數據來訓練CNN模型。

如果有數據集需求的可以聯繫我,或者是去隨機生成一些驗證碼數據集也是可以的,一個簡單的驗證碼數據集生成流程如下所示:

到這裡本文的工作就結束了,很高興在自己溫習回顧知識的同時能寫下點分享的東西出來,如果說您覺得我的內容還可以或者是對您有所啟發、幫助,還希望得到您的鼓勵支持,謝謝!

贊 賞 作 者

Python中文社區作為一個去中心化的全球技術社區,以成為全球20萬Python中文開發者的精神部落為願景,目前覆蓋各大主流媒體和協作平臺,與阿里、騰訊、百度、微軟、亞馬遜、開源中國、CSDN等業界知名公司和技術社區建立了廣泛的聯繫,擁有來自十多個國家和地區數萬名登記會員,會員來自以工信部、清華大學、北京大學、北京郵電大學、中國人民銀行、中科院、中金、華為、BAT、谷歌、微軟等為代表的政府機關、科研單位、金融機構以及海內外知名公司,全平臺近20萬開發者關注。

阿里雲雙十一活動來襲

長按掃描下方二維碼

即享雲伺服器新用戶1折起購

最低86元/年,一起拼團更優惠!

↓ ↓ 長按掃碼了解更多 ↓ ↓


【Python中文社區專屬拼團碼】

活動時間:2019年10月24日至2019年11月11日

活動對象:阿里雲新用戶,同一用戶限購1單。

▼ 點擊閱讀原文,即享阿里雲產品新用戶1折優惠

相關焦點

  • python生成驗證碼→處理驗證碼→建立CNN模型訓練→測試模型準確率→識別驗證碼
    、生成驗證碼本文要生成的驗證碼是由大寫字母或數字來組成典型4個字符的驗證碼,字母和數字是黑色的,背景是灰色的,然後加了兩條顏色隨機的幹擾線以及1000個隨機顏色隨機坐標的點。:def test_model():    model = CNNModel().cuda()    model.eval()  # 預測模式    # 載入模型    model.load_state_dict(torch.load(model_name))    logging.info('load cnn
  • 滑動驗證碼攻防對抗
    >續上篇,實戰筆記之X廠滑動驗證碼漏洞挖掘一、背景介紹  在業務安全領域,滑動驗證碼已經是國內繼,傳統字符型驗證碼之後的標配。眾所周知,打碼平臺和機器學習這兩種繞過驗證碼的方式,已經是攻擊者很主流的思路,不再闡述。冷滲透介紹的是一個冷門的繞過思路和防禦方案。這些積累,均來自於實戰之中,希望有用。二、黑產攻擊者知己知彼,百戰不殆。如果不清楚攻擊者的手段,又如何能制定防禦方案?1.
  • TensorFlow自動識別驗證碼(二)
    那麼今天這篇文章將對上篇文章中代碼進行修改用於實現對主流的CMS進行驗證碼的破解。0x001 破解步驟先回顧一下 tensorflow 的自動識別驗證碼的步驟由於後面三步基本都是tensorflow自動完成我們主要的工作是前兩步。
  • 這些驗證碼不再安全
    識別步驟如下:下載一定數量的目標驗證碼圖片,數量根據驗證圖片的複雜程度而定準備好一套標準的CNN圖像分類的項目模板,並做好相關的功課對項目模板進行簡單的參數調整,以適配當前問題的圖片尺寸將圖像輸入CNN,對輸出的結果和先驗標記的類型做誤差對比
  • 總結幾種常見 驗證碼的解決方案,非常有用!
    於是鹹魚總結了目前遇到過的的驗證碼類型以及總結出來的相關處理方式和大家聊一聊。現在市面上的驗證碼的類型大致有下面幾種類型。一、圖形驗證碼比較常見的英文數字組合成的圖形驗證碼,常常輔以各類幹擾線和扭曲圖片中的內容達到提高混淆難度的目的,並且通過加長圖片中的文字長度提升識別成本。
  • 自動化腳本無法處理驗證碼?Python圖片識別庫Tesseract實戰
    在Ui測試的時候,有時我們會遇到」元素以圖片的形式展示內容」(最經典的案例使驗證碼).這時傳統的文檔解析方案就失效了.因為其免費與較好的效果,許多的個人開發者以及一些較小的團隊在使用著 Tesseract ,諸如驗證碼識別、車牌號識別等應用中,不難見到 Tesseract 的身影。④Tesseract(/『tesərækt/) 這個詞的意思的本意是」超立方體」.不過這裡用到的,是一款以其命名的開源 OCR(Optical Character Recognition, 光學字符識別) 軟體。
  • 【CNN】多角度理解CNN
    Nielsen 的神經網絡與深度學習: http://neuralnetworksanddeeplearning.com/[5]Realistic views: http://setosa.io/ev/image-kernels/[6]Visualizing what ConvNets learn: http://cs231n.github.io/understanding-cnn
  • 最新驗證碼識別模擬登陸B站
    3.1 方法一:頁面截圖,將驗證碼區域進行裁剪保存使用此方法時,注意我們截取驗證碼圖片時需要截取完整,完整驗證碼截圖如下:首先做的當然是將點擊登錄後的頁面進行截圖,然後定位到驗證碼的位置,通過location()方法獲取驗證碼左上角的坐標,
  • 為什麼你的伺服器老被入侵 | Linux SSH密碼暴力破解實戰
    本文對目前流行的ssh密碼暴力破解工具進行實戰研究、分析和總結,對滲透攻擊測試和安全防禦具有一定的參考價值。一、SSH密碼暴力破解應用場景和思路1.應用場景(1)通過Structs等遠程命令執行獲取了root權限。(2)通過webshell提權獲取了root權限(3)通過本地文件包含漏洞,可以讀取linux本地所有文件。
  • mask rcnn訓練自己的數據集
    3D視覺工坊的第67篇文章前言最近迷上了mask rcnn,也是由於自己工作需要吧,特意研究了其原始碼,並基於自己的數據進行訓練~本博客參考:https://blog.csdn.net/disiwei1012/article/details/79928679#commentsedit實驗目的
  • NO.A.0013.基於Hydra/DDOS模擬黑客暴力破解linux用戶名和密碼/設置防禦規則
    二、黑客攻擊Linux伺服器&漏洞修復實戰1、在企業生產環境中,黑客攻擊Linux伺服器(業務系統、門戶網站、數據等)常見的攻擊手段,攻擊方式有哪些呢?SQL注入攻擊CC網頁攻擊SYN Flood攻擊勒索病毒攻擊上傳木馬文件DDOS攻擊暴力破解攻擊2、模擬Hydra暴力破解Linux伺服器設置防禦規則抵擋黑客攻擊&反攻擊實戰;學習Linux技術,後期從事Linux
  • pikachu-暴力破解漏洞
    .= '<p> csrf token error</p>'; }}set_token();可以看到就是在基於表單的暴力破解基礎上添加了Token驗證機制,Token並不能阻止暴力破解,因為token每次會變,但是可以利用工具去提前獲取token的值
  • Mask R-CNN官方實現「又」來了!基於PyTorch,訓練速度是原來2倍
    不過它是基於Caffe 2深度學習框架編寫的。這一次,在Caffe2項目併入PyTorch半年之後,Facebook換上了更受歡迎的PyTorch框架。除了更改框架,Mask R-CNN Benchmark相比它的「前輩」Detectron,訓練速度提高了一倍。
  • PokemonGO 安卓/蘋果最新破解版!(親測有效)
    蘋果/ 安卓 PokemonGO 下載破解版安裝教程如下先說明一下,遊戲官方還未開放中國區域,所以正常是沒辦法玩的另外玩的時候需要能收到驗證碼的手機及郵箱,註冊google帳號。需要 VPN免費翻牆下載及谷歌帳號註冊使用電腦端下載IPA破解文件:             http://pan.baidu.com/s/1eRB1RUE(建議下載到電腦桌面)這裡你可以用快用,同步推,itools等助手。
  • win10系統5次shift也一樣可以破解系統
    昨天在虛擬機中嘗試了win7按5次shift鍵破解windows系統密碼,win10簡單嘗試了一下沒有成功就沒再繼續,以為只有通過winPE這種方式修改
  • 【NLP】保姆級教程:手把手帶你CNN文本分類(附代碼)
    寫在前面本文是對經典論文《Convolutional Neural Networks for Sentence Classification[1]》的詳細復現,(應該是)基於TensorFlow 1.1以及python3.6。從數據預處理、模型搭建、模型訓練預測以及可視化一條龍講解,旨在為剛接觸該領域不知道如何下手搭建網絡的同學提供一個參考。
  • 【實戰】關於Swagger-UI下的滲透實戰
    實戰的時候遇到過一種情況,先是掃目錄掃出一個uploadtest上傳接口,在本地構造表單進行上傳,通過fuzz找到了上傳參數,但是上傳成功卻沒返迴路徑,只返回了一個file_id號,根據這個id號猜測後端是以id+上傳文件的絕對路徑保存在資料庫中,之後通過挖掘SQL注入,利用sqlnmap的--search -C參數找到了文件路徑。
  • 【NLP傻瓜式教程】手把手帶你CNN文本分類(附代碼)
    文章來源於NewBeeNLP,作者kaiyuan寫在前面本文是對經典論文《Convolutional Neural Networks for Sentence Classification[1]》的詳細復現,(應該是)基於TensorFlow 1.1以及python3.6。