NaixSpirit
7/7/2016 - 5:28 AM

Captcha

Captcha

# encoding: utf-8

class Captcha
  include Skeptick

  CATCH_TIME  = 15 * 60  # redis缓存

  attr_reader :key, :code

  def initialize
    @key  = SecureRandom.hex(10)  # 20位随机串用作标识符
    @code = SecureRandom.hex(2)   # 4位随机串用作验证码内容
    self.class.store(@key, @code)
  end

  def make
    tmp  = Tempfile.new(['captcha', '.png']) # GC的时候自动删除
    path = tmp.path

    image_size = '80x40'

    paper = rounded_corners_image(size: image_size, radius: 25) do
      set   :size, image_size
      image 'tile:granite:'
      apply '-brightness-contrast', '38x-33'
      apply :blur, '0x0.5'
    end

    text = image do
      canvas :none, size: '10x10'
      set    :pointsize, 30
      # set    :fill, 'gradient:#0e0-#050'
      write  self.code, left: 8, top: 30
      apply  :blur, '0x0.8'
    end

    torn = torn_paper_image(paper * text, spread: 12)

    png = convert(torn, to: path)
    png.build

    path
  end

  class << self

    # 用于redis中的key
    def cache_key key
      "captcha:#{key}"
    end

    def store key, code
      $redis.setex(cache_key(key), CATCH_TIME, code)
    end

    def valid? key, code
      return false if key.blank? || code.blank?
      status = ($redis.get(cache_key(key)) == code)
      $redis.del(cache_key(key))
      status
    end
  end
end