Skip to content

Commit e29e46b

Browse files
authored
Merge pull request #21 from segment-oj/improve-captcha-ztl
Improve captcha ztl
2 parents f10cc57 + 09416ba commit e29e46b

File tree

4 files changed

+97
-3
lines changed

4 files changed

+97
-3
lines changed

captcha/FiraCode-Regular.ttf

292 KB
Binary file not shown.

captcha/apps.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from django.apps import AppConfig
2+
from django.conf import settings
23

4+
import os.path
35

46
class CaptchaConfig(AppConfig):
57
name = 'captcha'
@@ -16,7 +18,7 @@ class CaptchaConfig(AppConfig):
1618
# try it until you find the best value
1719
font_size = 30
1820
# the font file of font
19-
font_family = "/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf"
21+
font_family = os.path.join(settings.BASE_DIR, "captcha", "FiraCode-Regular.ttf")
2022
# The number of dots on the pic to interfare
2123
dot_number = 100
2224
# The number of lines on the pic to interfare

captcha/tests.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,63 @@
11
from django.test import TestCase
2+
from captcha.tools import GenCaptcha
23

34
# Create your tests here.
5+
class GenCaptchaTest(TestCase):
6+
# set up test
7+
def setUp(self):
8+
self.captcha = GenCaptcha()
9+
10+
def testZ_get_random_color(self):
11+
for i in range(1, 1000):
12+
color = self.captcha.getRandomColor()
13+
14+
r = color[0]
15+
g = color[1]
16+
b = color[2]
17+
18+
r_in_range = r >= 0 and r <= 255
19+
g_in_range = g >= 0 and g <= 255
20+
b_in_range = b >= 0 and b <= 255
21+
22+
resault = r_in_range and g_in_range and b_in_range
23+
24+
self.assertTrue(resault)
25+
26+
def testY_get_random_char(self):
27+
for i in range(1, 1000):
28+
random_char = self.captcha.getRandomChar()
29+
30+
is_number = random_char >= "0" and random_char <= "9"
31+
is_upper = random_char >= "A" and random_char <= "Z"
32+
is_lower = random_char >= "a" and random_char <= "z"
33+
34+
is_char = is_number or is_lower or is_upper
35+
36+
is_o = random_char == 'o' or random_char == 'O'
37+
38+
resault = is_char and not is_o
39+
40+
self.assertTrue(resault)
41+
42+
def testX_check_similarity_false_far(self):
43+
color1 = (0, 0, 0)
44+
color2 = (255, 255, 255)
45+
46+
self.assertFalse(self.captcha.checkSimilarity(color1, color2))
47+
48+
def testW_check_similarity_false_close(self):
49+
color1 = (249, 244, 217)
50+
color2 = (69, 157, 245)
51+
52+
self.assertFalse(self.captcha.checkSimilarity(color1, color2))
53+
54+
def testV_check_similarity_same(self):
55+
color = (56, 1, 31)
56+
57+
self.assertTrue(self.captcha.checkSimilarity(color, color))
58+
59+
def testU_check_similarity_true(self):
60+
color1 = (69, 157, 245)
61+
color2 = (70, 158, 246)
62+
63+
self.assertTrue(self.captcha.checkSimilarity(color1, color2))

captcha/tools.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.utils import timezone
44
import datetime
55
import random
6+
import math
67
from PIL import Image, ImageDraw, ImageFont
78

89
from .apps import CaptchaConfig
@@ -33,8 +34,15 @@ def getRandomColor(self):
3334
def getRandomChar(self):
3435
random_num = str(random.randint(0, 9)) # numbers
3536
random_lower = chr(random.randint(97, 122)) # lower case letters
36-
random_upper = chr(random.randint(65, 90)) # upper case letters
37+
random_upper = chr(random.randint(65, 90)) # upper case letters
38+
39+
while random_lower == 'o':
40+
random_lower = chr(random.randint(97, 122))
41+
while random_upper == 'O':
42+
random_upper = chr(random.randint(65, 90))
43+
3744
random_char = random.choice([random_num, random_lower, random_upper])
45+
3846
return random_char
3947

4048
# draw random lines to interfere
@@ -57,6 +65,30 @@ def drawPoint(self, draw):
5765
y = random.randint(0, self.height)
5866
draw.point((x,y), fill = self.getRandomColor())
5967

68+
def checkSimilarity(self, color1, color2):
69+
r1 = color1[0]
70+
g1 = color1[1]
71+
b1 = color1[2]
72+
73+
r2 = color2[0]
74+
g2 = color2[1]
75+
b2 = color2[2]
76+
77+
r3 = (r1 - r2) / 256
78+
g3 = (g1 - g2) / 256
79+
b3 = (b1 - b2) / 256
80+
81+
color_diff = math.sqrt(r3 ** 2 + g3 ** 2 + b3 ** 2)
82+
83+
bright1 = ((r1 * 299) + (g1 * 587) + (b1 * 114))
84+
bright2 = ((r2 * 299) + (g2 * 587) + (b2 * 114))
85+
86+
bright_diff = abs(bright1 - bright2)
87+
88+
if color_diff < 0.7 or bright_diff < 100 * 255:
89+
return True
90+
return False
91+
6092
# create random picture
6193
# @param -> img save path
6294
# @return -> answer
@@ -79,7 +111,7 @@ def createImg(self, path):
79111
random_txt = self.getRandomChar()
80112
txt_color = self.getRandomColor()
81113
# avoid the text color is same to background color
82-
while txt_color == bg_color:
114+
while self.checkSimilarity(bg_color, txt_color):
83115
txt_color = self.getRandomColor()
84116

85117
# draw text

0 commit comments

Comments
 (0)