Skip to content

Instantly share code, notes, and snippets.

@vilisov
Created April 11, 2014 08:17
Show Gist options
  • Save vilisov/10449376 to your computer and use it in GitHub Desktop.
Save vilisov/10449376 to your computer and use it in GitHub Desktop.
import Crypto.Cipher.AES as aes
import base64
import random
from StringIO import StringIO
from PIL import Image, ImageFont, ImageDraw
def generate_id():
from common.conf import settings
imgtext = ''.join([str(random.randint(10, 90)) + '+' + str(random.randint(0, 9)) + '='])
# encrypt it
iv = ''.join([chr(random.randint(0, 255)) for i in range(16)])
a = aes.new(settings.CAPTCHAKEY, mode=aes.MODE_CBC, IV=iv)
pad_val = aes.block_size - (len(imgtext) % aes.block_size)
imgtext += chr(pad_val) * pad_val
crypttext = a.encrypt(imgtext)
# Return encoded ID safe for URLs
return base64.b16encode(iv) + base64.b16encode(crypttext)
def decrypt(captcha_id):
from common.conf import settings
iv = base64.b16decode(captcha_id[0:32])
crypttext = base64.b16decode(captcha_id[32:])
a = aes.new(settings.CAPTCHAKEY, mode=aes.MODE_CBC, IV=iv)
imgtext = a.decrypt(crypttext)
return imgtext[:5]
def generate_image(id):
from common.conf import settings
# decrypt captcha id
imgtxt = str(decrypt(id)).strip()
# render captcha image
font = ImageFont.truetype(font=settings.CAPTCHA_FONT, size=16)
sw, sh = font.getsize(imgtxt)
im = Image.new('RGBA', (sw, sh + 1), (255, 255, 255, 0))
d = ImageDraw.Draw(im)
d.text(xy=(0, -5), text=imgtxt, font=font, fill='black')
# return image data
buf = StringIO()
im.save(buf, 'PNG')
return buf.getvalue()
def check(usertext, captcha_id):
return usertext == str(sum(map(int, decrypt(captcha_id).strip('=').split('+'))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment