如今咱們通常訪問網頁都須要輸入驗證碼,好比博客園,有的甚至是經過手機驗證碼實時登陸。這樣作的目的主要仍是爲了防止其餘人的惡意訪問,好比爬蟲,下面就來看看驗證碼是如何實現的html
這二者都是給內存中讀寫文件使用的git
StringIO主要是以字符串的形式在內存中進行讀寫操做github
BytesIO主要是以二進制的形式在內存中進行讀寫操做django
from io import StringIO f = StringIO() f.write('luffy') f.write(',') f.write('你好') print(f.getvalue()) # getvalue,用於得到寫入後的str
效果:session
from io import BytesIO f = BytesIO() f.write('luffy'.encode("utf-8")) f.write('/t'.encode("utf-8")) # 很奇葩的是這裏轉移符也必須進行編碼,不然報錯 f.write('你好'.encode("utf-8")) print(f.getvalue()) # getvalue,用於得到寫入後的str
效果:app
# 該案例說明轉移符也須要進行轉換,它也可以轉成bytes類型dom
這裏我在項目下建立了一個utils文件,存放驗證碼文件,字體文件下載猛戳這裏ide
utils/code.pypost
import random from PIL import Image,ImageDraw,ImageFont,ImageFilter def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28): """ 生成一個120*30驗證碼框體,28字體,字體文件需本身導入 char_length表明生成5個字母 :return: """ code = [] # 用於存放每一個驗證碼 img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255)) draw = ImageDraw.Draw(img, mode='RGB') def rndChar(): """ 生成隨機字母A-Z :return: """ return chr(random.randint(65, 90)) def rndColor(): """ 生成隨機顏色 :return: """ return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)) # 寫文字 font = ImageFont.truetype(font_file, font_size) for i in range(char_length): char = rndChar() code.append(char) # 循環了char_length次並追加進去 h = random.randint(0, 4) draw.text([i * width / char_length, h], char, font=font, fill=rndColor()) # 寫干擾點 for i in range(40): draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor()) # 寫干擾圓圈 for i in range(40): draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor()) x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor()) # 畫干擾線 for i in range(5): 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=rndColor()) img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) return img, ''.join(code)
views.py字體
from django.shortcuts import render,HttpResponse,redirect from django.contrib import auth # 從utils文件夾下的code文件導入 check_code from utils.code import check_code def code(request): """ 生成圖片驗證碼 """ img,random_code = check_code() request.session['random_code'] = random_code from io import BytesIO # 實現了在內存中操做bytes stream = BytesIO() # 將二維碼最終轉爲png格式 img.save(stream, 'png') return HttpResponse(stream.getvalue()) def login(request): """ 用戶登錄 """ if request.method == 'GET': return render(request,'login.html') user = request.POST.get('user') pwd = request.POST.get('pwd') code = request.POST.get('code') if code.upper() != request.session['random_code'].upper(): return render(request,'login.html',{'msg':'驗證碼錯誤'}) # 經過auth模塊進行用戶認證 user = auth.authenticate(username=user,password=pwd) if user: return redirect('https://www.luffycity.com') return render(request, 'login.html', {'msg': '用戶名或密碼錯誤'})
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post"> {% csrf_token %} <p> <input type="text" name="user" placeholder="用戶名" /> </p> <p> <input type="password" name="pwd" placeholder="密碼" /> </p> <p> <input type="text" name="code" placeholder="驗證" /> <img onclick="changeImg(this);" src="/code/" alt="" title="點擊更換"> </p> <input type="submit" value="提交">{{ msg }} </form> <script> // 經過changeImg事件來更換圖片 function changeImg(ths) { ths.src = ths.src + '?'; console.log(ths.src); } </script> </body> </html>
# 這裏每次點擊圖片,圖片就會刷新,這是給url經過get的方式傳參數實現改變圖片驗證碼的,經過給/code/添加了一個js實現的
# 至於每次發送get請求爲何後面追加問號,按照我我的理解應該是語法規定,嘗試其餘字符均會報錯
# 對於這裏是如何利用random模塊實現驗證碼功能的,詳細內容能夠參考這裏