随机验证码的生成比较简单通常在注册用户的时候与邮箱或者手机信息接口相结合实现发送验证码功能,随机验证码只须要使用python内置的random随机数函数,调用random模块:import random,具体实现代码块前端
#随机验证码 def authCode(): code = '' for i in range(6): current = random.randrange(0,6)#randrange随机生成0-6的数字,但不包括6 if current != i: temp=chr(random.randint(65,90))#chr()加数字是ASCII码表中的大写A-Z字符 else: temp=random.randint(0,9)#randint随机生成65-90的数字,包括0和9 code += str(temp) #字符串拼接 return code #返回到随机生成的6位的验证码
图片验证码的生成是关于第三方库pillow的使用,使用pillow中的PIL中的一些方法生成验证码图片。其实pillow是在PIL的基础上进行修改加工的,由于PIL因为“年久失修”仅仅支持python2.7版本,因此pillow所以诞生,在PIL上面建立的兼容版本的pillow模块,示例代码块:python
#author:wylkjj #date:2019/12/19 #-*- coding:utf-8 -*- import random #导入随机函数模块 ''' 随机验证码图片 Image内部可能会有报错问题,主要是由于没有安装python2.7,不过能够忽略掉 Image:图片 ImageDraw:画笔 ImageFont:字符处理 ImageFilter: 滤镜,边界增强(阈值更大) ''' from PIL import Image, ImageDraw, ImageFont, ImageFilter ''' map(遍历序列):接收两个参数,一个是函数,一个是 Iterable, map 将传入的函数依次做用到序列的每一个元素,并把结果做为新的 Iterator 返回 ''' letter_cases = "qwertyupasdfghjkxcvb" # 小写字母,去除可能干扰的i,l,o,z upper_cases = letter_cases.upper() # 大写字母 numbers = ''.join(map(str, range(3, 10))) # 3-10数字 init_chars = ''.join((letter_cases, upper_cases, numbers)) def create_validate_code(size=(90, 30), chars=init_chars, img_type="GIF", mode="RGB", bg_color=(255, 255, 255), fg_color=(0, 0, 255), font_size=18, font_type="simfang.ttf", length=4, draw_lines=True, n_line=(1, 2), draw_points=True, point_chance = 2): ''' @todo: 生成验证码图片 @param size: 图片的大小,格式(宽,高),默认为(90, 30) @param chars: 容许的字符集合,格式字符串 @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG @param mode: 图片模式,默认为RGB @param bg_color: 背景颜色,默认为白色 @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF @param font_size: 验证码字体大小 @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf @param length: 验证码字符个数 @param draw_lines: 是否划干扰线 @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效 @param draw_points: 是否画干扰点 @param point_chance: 干扰点出现的几率,大小范围[0, 100] @return: [0]: PIL Image实例 @return: [1]: 验证码图片中的字符串 ''' width, height = size # 宽, 高 img = Image.new(mode, size, bg_color) # 建立图形 draw = ImageDraw.Draw(img) # 建立画笔 def get_chars(): '''生成给定长度的字符串,返回列表格式(以length的数量返回chars)''' return random.sample(chars, length) def create_lines(): '''绘制干扰线''' line_num = random.randint(*n_line) # 干扰线条数 for i in range(line_num): #起始点 begin = (random.randint(0, size[0]), random.randint(0, size[1])) #结束点 end = (random.randint(0, size[0]), random.randint(0, size[1])) draw.line([begin, end], fill=(0, 0, 0))#fill背景色 def create_points(): '''绘制干扰点''' chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100],省去了if else的复杂操做 for w in range(width): for h in range(height): tmp = random.randint(0, 100) if tmp > 100 - chance: draw.point((w, h), fill=(0, 0, 0))#背景色 def create_strs(): '''绘制验证码字符''' c_chars = get_chars() strs = ' %s ' % ' '.join(c_chars) # 每一个字符先后以空格隔开 font = ImageFont.truetype(font_type, font_size) font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3), strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines: create_lines() if draw_points: create_points() strs = create_strs() # 图形扭曲参数 params = [1 - float(random.randint(1, 2)) / 100, 0,0,0, 1 - float(random.randint(1, 10)) / 100, float(random.randint(1, 2)) / 500, 0.001, float(random.randint(1, 2)) / 500 ] img = img.transform(size, Image.PERSPECTIVE, params) # 建立扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界增强(阈值更大) return img, strs #生成验证码图片(测试时能够直接调用打印数据类型判断是否生成数据) img,strs=create_validate_code() print(type(img),type(strs))
#生成验证码图片 import io #要导入io模块 def checkCode(req): stream = io.BytesIO() #建立随机字符串 code #建立一张图片格式的字符串,将随机字符串写到图片上 img,code = create_validate_code() img.save(stream,"PNG") #将字符串形式的验证码放在Session中 req.session["checkCode"]=code return HttpResponse(stream.getvalue()) #把数据返回到前端
邮箱发送用户验证码一般结合上面的随机验证码一块儿使用:把从上面得到到的数据以邮箱的方式发送到用户邮箱中。注:发送邮件的又想要打开SMTP服务,生成受权码,用受权码代替邮箱的密码进行登陆操做,要使用与其邮箱相符的SMTP和端口号进行发送,下面例子使用的是网易163邮箱帐号,具体的开启SMTP服务的操做请自行百度。session
#邮箱发送功能 def email(email_list, content, subject="抽屉新热榜-用户注册"): msg = MIMEText(content, 'plain', 'utf-8') #发件人和发件邮箱 msg['From'] = formataddr(["抽屉新热榜",'######@163.com']) #邮件主题 msg['Subject'] = subject # SMTP服务 server = smtplib.SMTP("smtp.163.com", 25) #邮箱的smtp和端口 # SMTP登陆网易邮箱帐号 server.login("######@163.com", "######") # 发送的邮箱 server.sendmail('######@163.com', email_list, msg.as_string()) server.quit() #调用此函数就能够直接使用邮箱发送了 email(["要给发送的人的邮箱地址",], "要发送的内容")