溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Python實現隨機生成圖片驗證碼

發布時間:2022-01-19 13:29:22 來源:億速云 閱讀:203 作者:iii 欄目:開發技術
# 怎么用Python實現隨機生成圖片驗證碼

## 引言

在當今互聯網應用中,驗證碼(CAPTCHA)是防止惡意機器人和自動化腳本攻擊的重要手段。圖片驗證碼通過要求用戶識別并輸入扭曲或變形的字符來驗證操作者是否為真人。本文將詳細介紹如何使用Python生成隨機圖片驗證碼,涵蓋從基礎實現到高級定制的完整過程。

---

## 一、準備工作

### 1.1 所需工具庫
生成圖片驗證碼主要依賴以下Python庫:
- **Pillow**:Python圖像處理庫(PIL的分支)
- **random**:生成隨機字符和顏色
- **string**:提供字母和數字字符集
- **io**(可選):用于內存中處理圖像流

安裝Pillow:
```bash
pip install pillow

1.2 基礎原理

驗證碼生成流程: 1. 創建空白畫布 2. 生成隨機字符 3. 繪制干擾元素(噪點、線條) 4. 輸出圖片或字節流


二、基礎實現

2.1 生成空白畫布

from PIL import Image, ImageDraw, ImageFont
import random
import string

def generate_captcha(width=120, height=40):
    # 創建RGB模式白色背景圖
    image = Image.new('RGB', (width, height), (255, 255, 255))
    return image

2.2 添加隨機文本

def add_text(image, length=4):
    draw = ImageDraw.Draw(image)
    
    # 字符集:數字+大寫字母(排除易混淆字符)
    chars = string.digits + string.ascii_uppercase
    chars = chars.replace('0', '').replace('O', '').replace('1', '').replace('I', '')
    
    # 隨機選擇字符
    captcha_text = ''.join(random.choice(chars) for _ in range(length))
    
    # 加載字體(需提供字體文件路徑)
    try:
        font = ImageFont.truetype('arial.ttf', 24)
    except:
        font = ImageFont.load_default()
    
    # 繪制每個字符(隨機位置和顏色)
    for i, char in enumerate(captcha_text):
        x = 10 + i * 30 + random.randint(-5, 5)
        y = 5 + random.randint(-5, 5)
        color = (random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)
        draw.text((x, y), char, fill=color, font=font)
    
    return image, captcha_text

2.3 添加干擾元素

def add_noise(image):
    draw = ImageDraw.Draw(image)
    width, height = image.size
    
    # 繪制干擾點
    for _ in range(100):
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.point((x, y), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
    
    # 繪制干擾線
    for _ in range(3):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)
        draw.line((x1, y1, x2, y2), fill=(random.randint(0, 255), width=1)
    
    return image

2.4 完整調用示例

def simple_captcha():
    image = generate_captcha()
    image, text = add_text(image)
    image = add_noise(image)
    image.show()  # 顯示圖片
    print("驗證碼內容:", text)
    return image, text

三、進階優化

3.1 扭曲變形(增強安全性)

使用Pillow的ImageTransform實現文字扭曲:

from PIL import ImageTransform

def distort_text(image):
    width, height = image.size
    # 創建正弦波變形
    distort = ImageTransform.QuadTransform(
        (0, 0, 0, height,  # 左上、左下
         width, 0, width + random.randint(-5, 5), height)  # 右上、右下
    )
    return image.transform(image.size, Image.QUAD, distort.getdata())

3.2 背景漸變

def gradient_background(image):
    draw = ImageDraw.Draw(image)
    width, height = image.size
    for y in range(height):
        # 從上到下的漸變
        r = int(255 * (y / height))
        g = random.randint(200, 255)
        b = int(255 * (1 - y / height)))
        draw.line((0, y, width, y), fill=(r, g, b))
    return image

3.3 動態字符間距

修改add_text()函數中的字符繪制部分:

x_offset = 10
for i, char in enumerate(captcha_text):
    # 動態調整間距(基于字符寬度)
    char_width = font.getsize(char)[0]
    x = x_offset + random.randint(-3, 3)
    y = 5 + random.randint(-5, 5)
    draw.text((x, y), char, fill=color, font=font)
    x_offset += char_width + random.randint(2, 8)

四、Web應用集成

4.1 生成驗證碼API(Flask示例)

from flask import Flask, make_response
import io

app = Flask(__name__)

@app.route('/captcha')
def get_captcha():
    image, text = simple_captcha()
    
    # 存儲驗證碼文本(實際應使用Redis等存儲)
    app.config['CAPTCHA_TEXT'] = text
    
    # 轉換為字節流
    img_io = io.BytesIO()
    image.save(img_io, 'PNG')
    img_io.seek(0)
    
    response = make_response(img_io.getvalue())
    response.headers['Content-Type'] = 'image/png'
    return response

4.2 驗證邏輯

@app.route('/verify', methods=['POST'])
def verify():
    user_input = request.form.get('captcha', '').upper()
    if user_input == app.config.get('CAPTCHA_TEXT', ''):
        return "驗證成功"
    return "驗證失敗"

五、安全性增強建議

  1. 時效性控制:驗證碼應設置有效期(通常2-5分鐘)
  2. 使用次數限制:每個驗證碼僅允許驗證一次
  3. 日志監控:記錄失敗嘗試次數,防止暴力破解
  4. 行為分析:結合鼠標軌跡等生物特征驗證
  5. 多因素驗證:對敏感操作使用短信+圖片雙驗證

六、完整代碼示例

import random
import string
from PIL import Image, ImageDraw, ImageFont, ImageFilter

class CaptchaGenerator:
    def __init__(self, width=160, height=60, char_length=6):
        self.width = width
        self.height = height
        self.char_length = char_length
        self._chars = self._get_valid_chars()
        
    def _get_valid_chars(self):
        """排除易混淆字符"""
        chars = string.digits + string.ascii_uppercase
        exclude = {'0', 'O', '1', 'I', 'L', '7', 'Z', '2', 'S', '5', 'B', '8'}
        return ''.join(c for c in chars if c not in exclude)
    
    def generate(self):
        # 創建漸變背景
        image = Image.new('RGB', (self.width, self.height), (255, 255, 255))
        draw = ImageDraw.Draw(image)
        for x in range(self.width):
            for y in range(self.height):
                r = x + y if (x + y < 255) else 255
                g = 255 - x if (255 - x > 0) else 0
                b = y
                draw.point((x, y), fill=(r, g, b))
        
        # 生成驗證碼文本
        captcha_text = ''.join(random.choice(self._chars) for _ in range(self.char_length))
        
        # 繪制文字(帶扭曲)
        font_path = 'arial.ttf'  # 需替換實際路徑
        try:
            font = ImageFont.truetype(font_path, 28)
        except:
            font = ImageFont.load_default()
            
        x_offset = 5
        for char in captcha_text:
            # 隨機旋轉角度
            char_image = Image.new('RGBA', (30, 40))
            char_draw = ImageDraw.Draw(char_image)
            char_draw.text((0, 0), char, font=font, fill=(random.randint(0, 180), 
                                                         random.randint(0, 180),
                                                         random.randint(0, 180)))
            
            # 隨機旋轉和變形
            char_image = char_image.rotate(random.randint(-30, 30), expand=1)
            char_image = char_image.resize((30, 40))
            
            # 粘貼到主圖像
            y_offset = random.randint(0, 10)
            image.paste(char_image, (x_offset, y_offset), char_image)
            x_offset += 30 + random.randint(-5, 5)
        
        # 添加干擾
        self._add_noise(image)
        image = image.filter(ImageFilter.SMOOTH)
        
        return image, captcha_text
    
    def _add_noise(self, image):
        draw = ImageDraw.Draw(image)
        for _ in range(100):  # 干擾點
            x = random.randint(0, self.width)
            y = random.randint(0, self.height)
            draw.point((x, y), fill=(random.randint(0, 255), 
                                   random.randint(0, 255),
                                   random.randint(0, 255)))
        
        for _ in range(5):  # 干擾線
            x1 = random.randint(0, self.width)
            y1 = random.randint(0, self.height)
            x2 = random.randint(0, self.width)
            y2 = random.randint(0, self.height)
            draw.line((x1, y1, x2, y2), fill=(random.randint(0, 255),
                                            random.randint(0, 255),
                                            random.randint(0, 255)), width=1)

# 使用示例
if __name__ == '__main__':
    generator = CaptchaGenerator()
    image, text = generator.generate()
    image.save('captcha.png')
    print("生成的驗證碼:", text)

結語

本文從基礎到進階詳細介紹了Python生成圖片驗證碼的實現方法。實際應用中,建議: 1. 定期更換驗證碼樣式 2. 結合后端邏輯進行嚴格驗證 3. 根據業務需求調整復雜度

驗證碼技術需要與其它安全措施配合使用,才能構建更完善的防御體系。完整的項目代碼已包含文中關鍵實現,讀者可直接擴展使用。 “`

(注:實際字符數約2400字,包含代碼示例和詳細說明)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女