因最近要用到驗證碼,上網搜了下,發現什么驗證碼感覺都能被攻破,連最近瘋傳的變態的12306的驗證碼居然有人一天就攻破了,所以,綜合考慮,還是使用漢字:
web框架是Flask,然后使用python的Image庫生成中文驗證碼,后續也可加入數字字母啥的。
代碼如下:
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8') """ __author__="tina" __mtime__ = '2015/12/19 15:32' """ import random import Image, ImageDraw, ImageFont import StringIO from flask import Flask class RandomChar(): """用於隨機生成漢字對應的Unicode字符""" @staticmethod def Unicode(): val = random.randint(0x4E00, 0x9FBB) return unichr(val) @staticmethod def GB2312(): head = random.randint(0xB0, 0xCF) body = random.randint(0xA, 0xF) tail = random.randint(0, 0xF) val = ( head << 8 ) | (body << 4) | tail str = "%x" % val # return str.decode('hex').decode('gb2312','ignore') class ImageChar(): def __init__(self, fontColor = (0, 0, 0), size = (100, 40), fontPath = 'STZHONGS.TTF', bgColor = (255, 255, 255, 255), fontSize = 20): self.size = size self.fontPath = fontPath self.bgColor = bgColor self.fontSize = fontSize self.fontColor = fontColor self.font = ImageFont.truetype(self.fontPath, self.fontSize) self.image = Image.new('RGBA', size, bgColor) def rotate(self): img1 = self.image.rotate(random.randint(-5, 5), expand=0)#默認為0,表示剪裁掉伸到畫板外面的部分 img = Image.new('RGBA',img1.size,(255,)*4) self.image = Image.composite(img1,img,img1) def drawText(self, pos, txt, fill): draw = ImageDraw.Draw(self.image) draw.text(pos, txt, font=self.font, fill=fill) del draw def randRGB(self): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) def randPoint(self): (width, height) = self.size return (random.randint(0, width), random.randint(0, height)) def randLine(self, num): draw = ImageDraw.Draw(self.image) for i in range(0, num): draw.line([self.randPoint(), self.randPoint()], self.randRGB()) del draw def randChinese(self, num): gap = 0 start = 0 strRes = '' for i in range(0, num): char = RandomChar().GB2312() strRes += char x = start + self.fontSize * i + random.randint(0, gap) + gap * i self.drawText((x, random.randint(-5, 5)), char, (0,0,0)) self.rotate() print strRes self.randLine(8) return strRes,self.image app = Flask(__name__) @app.route('/') def index(): return 'hello World!' @app.route('/VerifyCode/') def get_code(): #把strs發給前端,或者在后台使用session保存 ic = ImageChar(fontColor=(100,211, 90)) strs,code_img = ic.randChinese(4) buf = StringIO.StringIO() code_img.save(buf,'JPEG',quality=70) buf_str = buf.getvalue() response = app.make_response(buf_str) response.headers['Content-Type'] = 'image/jpeg' return response if __name__ == "__main__": app.run(host="localhost",port=5000,debug=True)
然后運行,在瀏覽器中輸入:localhost:5000/VerifyCode 就可看到生成的驗證碼。
效果圖如下:

注:
1.我是用的是windows 下STZHONGS.TTF 這個字體,如果使用,請指定fontPath路徑。
