行为验证码验证类型的讲解

简介: 最近在开发行为验证码,经常触及到关于验证类型的相关内容。但使用起来不太熟练,闲暇之余,总结一下我对行为验证码验证类型的理解。

前言

近在开发行为验证码,经常触及到关于验证类型的相关内容。但使用起来不太熟练,闲暇之余,总结一下我对行为验证码验证类型的理解。

1.PNG


验证类型概述

2.PNG

滑动拼图

创新行为式验证,轻松一滑完成拼图,体验极佳,秒速通过验证。简洁高效,在保障用户极致体验的同时,抵御机器风险。适用于追求用户体验的场景。

# 生成背景图basemap1=Image.open(bg).convert("RGBA")  # 背景图ifbasemap1.size!=size:  # 需要裁切或拉伸basemap1=Graphics.crop(basemap1, size[0], size[1])
puzzle1=Image.open(url_absolute(img)).convert("RGBA")  # 方块图,蒙板# 旋转角度ifrotate==2:
angle=randint(0, 360)
elifrotate==1:
angle=choice([0, 90, 180, 270])
else:
angle=0# angle = 45ifangle: puzzle1=puzzle1.rotate(angle, resample=Image.Resampling.BILINEAR)
puzzle1.putalpha(ImageEnhance.Brightness(puzzle1.split()[3]).enhance(alpha))  # 设置透明度,0-1之间# 产生随机位置img_size=puzzle1.size# 滑动图片尺寸spacing=0# 滑动图片在底图位置四周间距,暂时使用0,小图片中的图案本身有20px边距# 随机位置x=randint(img_size[0] +spacing, size[0] -img_size[0] -spacing)
y=randint(spacing, size[1] -img_size[1] -spacing)
basemap1.paste(puzzle1, (x, y), puzzle1)  # 拷贝# 方块滑动图# basemap2 = Image.open(url_absolute(bg)).convert("RGBA")basemap2=Image.open(bg).convert("RGBA")
ifbasemap2.size!=size:  # 需要裁切或拉伸basemap2=Graphics.crop(basemap2, size[0], size[1])
puzzle2=Image.open(url_absolute(img)).convert("RGBA")
ifangle: puzzle2=puzzle2.rotate(angle, resample=Image.Resampling.BILINEAR)  # 旋转basemap2=basemap2.crop((x, y, x+img_size[0], y+img_size[1]))  # 裁切puzzle2.paste(basemap2, (0, 0), puzzle2)
# 替换成长条形滑动块strip=Image.new('RGBA', (img_size[0], size[1]), (255, 255, 255, 0))
strip.paste(puzzle2, (0, y), puzzle2)  # 拷贝


文字点选

顺序点击图中文字,全新行为验证,安全性极高,保障验证安全。提高机器识别难度的同时,保证真实用户可读。适用于安全要求较高的业务场景。

defrandom_character(self, length=None, type=[0, 1, 2, 3], repeat=False):
"""  生成随机字符  :param length: 生成的字符长度,几个字符  :param type: [0] 数字,[1] 大写字母,[2]小写字母,[3] 特殊字符  :param repeat: 是否允许重复字符  :return [("A", 1, "大写字母"), ("8", 0, "数字"), ("a", 2, "小写字母"), ("", 3, "高跟鞋") ...]  """iflengthisNone: length=self.str_count# length = 10# type = [0]string="".join(dict([(key, {
0: "2345678923456789",
1: "ABCDEFGHJKLMNQRTY",
2: "abcdefghijkmnqrty",
3: "",
  }[key]) forkeyintype]).values())
r= []
foriinrange(length):
ifrepeat:  # 允许重复s=choice(string)
t=Inference.char_type(s)
r.append((s, t[0], t[1]))
else:
anti=0# 防止死循环,尝试一定次数后允许字符重复whileTrue:
anti+=1s=choice(string)
t=Inference.char_type(s)
st="".join([it[0] foritinr])
ifsnotinstoranti>30:
r.append((s, t[0], t[1]))
break# 替换 n 个字母为图形字符if3intype:
index=sample([iforiinrange(length)], randint(0, length))  # 随机一组索引值:[0, 3, 1]icon_char=sample(self.icon_str, len(index))  # 随机取出 n 组特殊字符x=0foriinindex:
# r = Inference.char_replace(r, i, icon_char[x][1])r[i] = (icon_char[x][1], 3, icon_char[x][2])
x+=1returnr


语序点选

根据中文语义,按顺序依次点击图中文字,语义理解能力结合行为轨迹。适用于安全要求较高的业务场景。

下面举例说说的干扰点与干扰线的制作:

# 噪线foriinrange(line_count):
x1=randint(0, size[0])
x2=randint(0, size[0])
y1=randint(0, size[1])
y2=randint(0, size[1])
draw.line((x1, y1, x2, y2), fill=Word.get_random_color())
# 噪点foriinrange(point_count):
draw.point([randint(0, size[0]), randint(0, size[1])], fill=Word.get_random_color())
x=randint(0, size[0])
y=randint(0, size[1])
draw.arc((x, y, x+4, y+4), 0, 90, fill=Word.get_random_color())


字体识别

点击与其它字符不同字体的文字,用户仅需一次点击,即可进行安全验证。适用于安全要求超高的业务场景。

# 字体识别iftypein (10, 11, 12):  # 789生成成语/固定字符str_count=1str_inter=numeric(str_inter, 2, 20)  # 干扰字符不能少于2v_font=sample(ttf, 2)  # 随机选出两种字体string= []
foriinrange(str_count+str_inter):
iftypein (10, 11, 12):  # 字体识别,只使用两种字体font_file=v_font[0] ifi==0elsev_font[1]
else:  # 随机字体font_file=choice(ttf)
font=ImageFont.truetype(url_absolute(font_file), size=font_size)
# 成语/使用固定字符,前n个字符使用成语字符random_char=idiom[i:i+1] ifidiomelse""# 随机字符串及补充固定字符时追加干扰字符ifrandom_char=="":
head=randint(0xb0, 0xf7)
body=randint(0xa1, 0xfe)
random_char=bytes.fromhex(f'{head:x}{body:x}').decode("gb18030")
# print(random_char, font_file)# 随机位置anti=0# 防止字体设置过大或者图片设置过小,导致死循环,尝试一定次数后允许字符重叠whileTrue:  # 防止文字重叠anti+=1x=randint(0, size[0] -font_size)
y=randint(0, size[1] -font_size)
find=Trueforsinstring:
ifabs(x-s[1]) <font_sizeandabs(y-s[2]) <font_size:
find=Falsebreakiffindornotstringoranti>20: break# 创建文字图片,可旋转str_bg=Image.new("RGBA", (font_size, font_size), (255, 255, 255, 0))  # 文字用空白图层str_draw=ImageDraw.Draw(str_bg)
str_draw.text((0, 0), random_char, Word.get_random_color(), font=font)  # 添加文字angle=randint(-75, 75) ifrotateelse0# 是否随机角度str_bg=str_bg.rotate(angle, resample=Image.Resampling.BILINEAR, expand=0)  # 随机旋转basemap.paste(str_bg, (x, y), str_bg)  # 图片与文字合并# 保存随机字符及位置string.append([random_char, x, y, -angle])  # 字符、x、y、角度(正负转换,转用CSS顺时针旋转形式)


空间推理

根据提示,点击对应的元素。逻辑解题能力结合图形符号等元素识别能力。适用于安全要求超高的业务场景。

下面举例几种验证方式:

defsend_color2differ(self):
""" 请点击一个颜色不一样的字符 """color=self.color_name(2)  # 获取 2 组带中文名称的颜色 [('蓝色', '#0000FF'), ]data= []
foriinrange(self.str_count):
# data/在图片上生成的数据data.append({
"str": self.string[i][0],  # 字符内容"X": self.coord[i][0],  # x 位置"Y": self.coord[i][1],  # y 位置"color": color[0][1] ifi==0elsecolor[1][1],
"angle": self.angle[i],
"icon": Trueifself.string[i][1] ==3elseFalse,  # 是否为图形字符            })
# hint/操作说明文字hint=f'请点击一个 <i>颜色不一样</i> 的 <i>{self.string[0][2]}</i>'str= [(data[0]["str"], data[0]["X"], data[0]["Y"], data[0]["angle"]), ]
return {"data": data, "str": str, "hint": hint}
defsend_color2capital(self):
""" 请点击蓝色字母对应的大写 """direc=choice([1, 2])  # 随机一种方式,大写 to 小写/小写 to 大写color=self.color_name()  # 获取 n 组带中文名称的颜色 [('蓝色', '#0000FF'), ]self.string=self.random_character(type=[direc])
data= []
foriinrange(self.str_count):
# data/在图片上生成的数据data.append({
"str": self.string[i][0],  # 字符内容"X": self.coord[i][0],  # x 位置"Y": self.coord[i][1],  # y 位置"color": color[i][1],
"angle": self.angle[i],
"icon": Trueifself.string[i][1] ==3elseFalse,  # 是否为图形字符            })
data[0]["str"] =data[1]["str"].swapcase()
# hint/操作说明文字hint=f'请点击 <i>{color[0][0]}字母</i> 对应的 <i>{"大写"ifdirec==1else"小写"}</i>'str= [(data[1]["str"], data[1]["X"], data[1]["Y"], data[1]["angle"]), ]
return {"data": data, "str": str, "hint": hint}


总结

以上便是本文的全部内容,相关代码我已经放上 Github 了,https://github.com/KgCaptcha,这里我做了一个示例:https://www.kgcaptcha.com/demo/ 

相关文章
|
3月前
|
SQL 测试技术 数据安全/隐私保护
密码组件校验规则该如何测试?
密码组件校验规则该如何测试?
|
4月前
表单常用验证数据类型,验证一切(checkEverything)
表单常用验证数据类型,验证一切(checkEverything)
验证码60秒发送(获取验证码)demo效果示例(整理)
验证码60秒发送(获取验证码)demo效果示例(整理)
|
安全 开发工具
【干货】验证码的常见类型总结
验证码是一种区分用户是计算机和人的公共全自动程序。简单来说,验证码就是验证操作是人还是机器。下面我就总结一下常见的验证码类型都有哪些?
【干货】验证码的常见类型总结
083.验证歌德巴赫猜想
083.验证歌德巴赫猜想
62 0
|
Java
Servlet实现登录带有验证码验证案例
Servlet实现登录带有验证码验证案例
111 0
|
JavaScript Java
实现登录时进行校验验证码的功能
JavaEE中,实现登录时进行校验验证码的功能(图文并茂!!!)
实现登录时进行校验验证码的功能
【TP5.1】验证码校验 ---验证器使用
【TP5.1】验证码校验 ---验证器使用
213 0
【TP5.1】验证码校验 ---验证器使用
|
JavaScript 前端开发
简单的验证码功能
简单的验证码功能
简单的验证码功能
|
前端开发
手机号校验工具函数
工作中遇到的手机号校验的需求