Vérification comportementale innovante, complétez facilement le puzzle d'un seul coup, excellente expérience, réussissez la vérification en quelques secondes. Simple et efficace, il protège des risques machines tout en garantissant une expérience utilisateur ultime. Convient aux scénarios qui recherchent l’expérience utilisateur.
# 生成背景图 basemap1 = Image.open(bg).convert("RGBA") # 背景图 if basemap1.size != size: # 需要裁切或拉伸 basemap1 = Graphics.crop(basemap1, size[0], size[1]) puzzle1 = Image.open(url_absolute(img)).convert("RGBA") # 方块图,蒙板 # 旋转角度 if rotate == 2: angle = randint(0, 360) elif rotate == 1: angle = choice([0, 90, 180, 270]) else: angle = 0 # angle = 45 if angle: 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") if basemap2.size != size: # 需要裁切或拉伸 basemap2 = Graphics.crop(basemap2, size[0], size[1]) puzzle2 = Image.open(url_absolute(img)).convert("RGBA") if angle: 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) # 拷贝
Cliquez séquentiellement sur le texte dans l'image, une nouvelle vérification comportementale, une sécurité extrêmement élevée, assurant la sécurité de la vérification. Tout en améliorant la difficulté de la reconnaissance automatique, il garantit la lisibilité par les utilisateurs réels. Convient aux scénarios commerciaux avec des exigences de sécurité élevées.
def random_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, "高跟鞋") ...] """ if length is None: length = self.str_count # length = 10 # type = [0] string = "".join(dict([(key, { 0: "2345678923456789", 1: "ABCDEFGHJKLMNQRTY", 2: "abcdefghijkmnqrty", 3: "", }[key]) for key in type]).values()) r = [] for i in range(length): if repeat: # 允许重复 s = choice(string) t = Inference.char_type(s) r.append((s, t[0], t[1])) else: anti = 0 # 防止死循环,尝试一定次数后允许字符重复 while True: anti += 1 s = choice(string) t = Inference.char_type(s) st = "".join([it[0] for it in r]) if s not in st or anti > 30: r.append((s, t[0], t[1])) break # 替换 n 个字母为图形字符 if 3 in type: index = sample([i for i in range(length)], randint(0, length)) # 随机一组索引值:[0, 3, 1] icon_char = sample(self.icon_str, len(index)) # 随机取出 n 组特殊字符 x = 0 for i in index: # r = Inference.char_replace(r, i, icon_char[x][1]) r[i] = (icon_char[x][1], 3, icon_char[x][2]) x += 1 return r
Semantique chinoise, cliquez sur le texte dans l'image dans l'ordre, et la capacité de compréhension sémantique est combinée avec la trajectoire comportementale. Convient aux scénarios commerciaux avec des exigences de sécurité élevées.
Ce qui suit est un exemple de production de points d'interférence et de lignes d'interférence :
# 噪线 for i in range(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()) # 噪点 for i in range(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())
Cliquez sur le texte qui est dans un autre la police des autres caractères. La vérification de sécurité ne prend qu'un seul clic. Convient aux scénarios commerciaux avec des exigences de sécurité extrêmement élevées.
# 字体识别 if type in (10, 11, 12): # 789生成成语/固定字符 str_count = 1 str_inter = numeric(str_inter, 2, 20) # 干扰字符不能少于2 v_font = sample(ttf, 2) # 随机选出两种字体 string = [] for i in range(str_count + str_inter): if type in (10, 11, 12): # 字体识别,只使用两种字体 font_file = v_font[0] if i == 0 else v_font[1] else: # 随机字体 font_file = choice(ttf) font = ImageFont.truetype(url_absolute(font_file), size=font_size) # 成语/使用固定字符,前n个字符使用成语字符 random_char = idiom[i:i+1] if idiom else "" # 随机字符串及补充固定字符时追加干扰字符 if random_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 # 防止字体设置过大或者图片设置过小,导致死循环,尝试一定次数后允许字符重叠 while True: # 防止文字重叠 anti += 1 x = randint(0, size[0] - font_size) y = randint(0, size[1] - font_size) find = True for s in string: if abs(x - s[1]) < font_size and abs(y - s[2]) < font_size: find = False break if find or not string or anti > 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) if rotate else 0 # 是否随机角度 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顺时针旋转形式)
Selon les invites, cliquez sur l'élément correspondant. Capacité de résolution logique de problèmes combinée à la capacité de reconnaître des symboles graphiques et d’autres éléments. Convient aux scénarios commerciaux avec des exigences de sécurité extrêmement élevées.
Voici quelques exemples de méthodes de vérification :
def send_color2differ(self): """ 请点击一个颜色不一样的字符 """ color = self.color_name(2) # 获取 2 组带中文名称的颜色 [('蓝色', '#0000FF'), ] data = [] for i in range(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] if i == 0 else color[1][1], "angle": self.angle[i], "icon": True if self.string[i][1] == 3 else False, # 是否为图形字符 }) # 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} def send_color2capital(self): """ 请点击蓝色字母对应的大写 """ direc = choice([1, 2]) # 随机一种方式,大写 to 小写/小写 to 大写 color = self.color_name() # 获取 n 组带中文名称的颜色 [('蓝色', '#0000FF'), ] self.string = self.random_character(type=[direc]) data = [] for i in range(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": True if self.string[i][1] == 3 else False, # 是否为图形字符 }) data[0]["str"] = data[1]["str"].swapcase() # hint/操作说明文字 hint = f'请点击 <i>{color[0][0]}字母</i> 对应的 <i>{"大写" if direc == 1 else "小写"}</i>' str = [(data[1]["str"], data[1]["X"], data[1]["Y"], data[1]["angle"]), ] return {"data": data, "str": str, "hint": hint}
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!