captcha на python
2010-02-04
python
captcha
Используемые компоненты
Image, ImageDraw, ImageFonts
1) Генерируем кодовое слово
key = ''.join([choice('QWERTYUIOPLKJHGFDSAZXCVBNM1234567890') for i in xrange(5)] )
2) Создаем картинку с фоном
img = Image.new('RGB', (100,30), 0xffffff )
draw = ImageDraw.Draw(img)
for i in xrange(40):
draw.line( [(randint(0,100),randint(0,30)),
(randint(0,100),randint(0,30))] ,
randint(0, 0xffffff), 1)
здесь мы рисуем 40 разных линий на белом фоне
3) Выводим текст
font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeMono.ttf', 32)
draw.text( (0,0), key, 0, font)
файл шрифтов у вас должен быть
4) Получить картинку формата jpeg в виде строки для передачи клиенту (не сохраняя на сервере)
f = StringIO.StringIO()
img.save(f, "JPEG")
raw = f.getvalue()
Функция целиком
# coding: utf-8
def captcha():
import StringIO
import Image, ImageDraw, ImageFont
from random import randint, choice
key = ''.join( [choice('QWERTYUIOPLKJHGFDSAZXCVBNM1234567890') for i in xrange(5)] )
img = Image.new('RGB', (100,30), 0xffffff )
draw = ImageDraw.Draw(img)
for i in xrange(40):
draw.line( [(randint(0,100),randint(0,30)),(randint(0,100),randint(0,30))] , randint(0, 0xffffff), 1)
font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeMono.ttf', 32)
draw.text( (0,0), key, 0, font)
f = StringIO.StringIO()
img.save(f, "JPEG")
raw = f.getvalue()
return key,raw
Пример капчи:
Один из вариантов использования
На нашу веб страницу вешаем эту капчу
Когда клиент подключается к
/capcha, мы отдаем ему данные из
raw переменной, при этом нужно у клиента установить куку - хеш от
key (например md5) и записать в БД/файл этот ключ.
@get('/captcha')
def retcapcha():
key, raw = captcha()
response.set_cookie('capcha_hash', hash(key))
db.save(key)
response.headers['Content-Type'] = 'image/jpeg'
return key
Когда от клиента придут данные где он ввел капчу (key) + хеш в куках, проверяем произведен ли этот хеш от присланного ключа, далее ищем ключ в БД/файле, если нашли, то капча была введена правильно, при этом ключ нужно удалить из БД/файла, что-б нельзя было повторно использовать.
Данный метод не позволяет открывать страницы с капчей параллельно у одного клиента, т.к. кука будет перетераться. Что-б это обойти, хеш можно передавать в html страницу где будет капча и при отправке клиентом капчи к нам летит и хеш.