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

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

前言

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

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/ 

相关文章
|
4月前
|
JavaScript NoSQL Redis
Vue中实现修改邮箱、手机号等流程的大致过程、验证码由后端的redis生成验证(版本1.0)
这篇文章记录了在Vue中实现修改手机号和邮箱的大致流程,包括使用过滤器部分隐藏展示的手机号和邮箱,以及通过点击触发路由跳转的便捷方式。文章还描述了旧号码和新号码验证的界面实现,其中验证码由后端生成并通过弹窗展示给用户,未来可以接入真正的手机验证码接口。此外,还提供了修改邮箱的页面效果截图,并强调了学习是一个永无止境的过程。
Vue中实现修改邮箱、手机号等流程的大致过程、验证码由后端的redis生成验证(版本1.0)
|
2月前
jcaptcha集群时验证码不能验证的问题
jcaptcha集群时验证码不能验证的问题
31 3
|
2月前
|
存储 前端开发 Java
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
本文介绍了使用Kaptcha插件在SpringBoot项目中实现验证码的生成和验证,包括后端生成验证码、前端展示以及通过session进行验证码校验的完整前后端代码和配置过程。
267 0
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
|
7月前
|
JavaScript Java
java生成验证码并进行验证
java生成验证码并进行验证
|
4月前
|
存储 NoSQL Java
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
该博客文章展示了如何在Linux虚拟机上使用Redis和Jedis客户端实现手机验证码的验证功能,包括验证码的生成、存储、验证以及限制每天发送次数的逻辑,并提供了测试结果截图。
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
|
6月前
|
前端开发 JavaScript
阿里云验证码2.0 验证时报错 前端页面获取的验证参数有问题,动态JS加载失败,请问怎么解决啊?急,急,急。
用户反馈校验时遇到错误,日志显示验证码参数获取异常。采用无痕验证,失败后,返回`{captchaResult:false,bizResult:false}`,未触发滑块二次验证。
|
安全 开发工具 UED
告别验证码烦恼,轻松完成文字点选验证
文字点选验证码,作为一种创新的验证方式,正在逐渐取代传统的输入文字或数字的验证方式,为用户带来了更简单、直观的验证体验。它通过点击包含特定文字或物体的图片来完成验证,摆脱了繁琐的输入过程,让用户告别验证码的烦恼。
|
前端开发
图形验证码验证行式的笔记
最近在做关于验证码项目的时候,从交互的角度梳理了验证码的验证行式,今天总结一下验证码在产品中出现的验证行式。
图形验证码验证行式的笔记
KgCaptcha 图形验证码自定义验证行式
图形验证码是一种很常见的行为验证码,其中滑动拼图,用户只需要轻轻滑动滑块填充拼图,即可完成安全验证。通常包括嵌入式、触发式和弹出式三种形式。
KgCaptcha 图形验证码自定义验证行式
|
搜索推荐 前端开发 API
这个验证码合集,从图形到行为验证,你想要的都有-KgCaptcha
凯格行为验证码 - KgCaptcha,采用业界通用的API接口方式,对接轻松简单,即可享受带来的产品服务能力。自定义样式及风控等级,完全个性化的设置,与你的应用完美融合。
这个验证码合集,从图形到行为验证,你想要的都有-KgCaptcha