Home

Tags

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
Пример капчи:

Один из вариантов использования

На нашу веб страницу вешаем эту капчу
<img src="/capcha" />

Когда клиент подключается к /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 страницу где будет капча и при отправке клиентом капчи к нам летит и хеш.