captcha.rb 1.2 KB
require 'rubygems'
require 'ezcrypto'
class Captcha
  NUMBERS   = (1..9).to_a
  OPERATORS = [:+, :-, :*]

  attr_reader :x, :y, :operator

  def initialize(x=nil, y=nil, operator=nil)
    @x = x || NUMBERS.sort_by{rand}.first
    @y = y || NUMBERS.sort_by{rand}.first
    @operator = operator || OPERATORS.sort_by{rand}.first
  end

  # Only the #to_secret is shared with the client.
  # It can be reused here to create the Captcha again
  def self.from_secret(secret)
    yml = cipher.decrypt64 secret
    args = YAML.load(yml)
    new(args[:x], args[:y], args[:operator])
  end

  def self.cipher
    EzCrypto::Key.with_password key, 'bad_fixed_salt'
  end

  def self.key
    'ultrasecret'
  end

  
  def check(answer)
    answer == solution
  end
  
  def task
    "#{@x} #{@operator.to_s} #{@y}"
  end
  def task_with_questionmark
    "#{@x} #{@operator.to_s} #{@y} = ?"
  end
  alias_method :to_s, :task

  def solution
    @x.send @operator, @y
  end

  def to_secret
    cipher.encrypt64(to_yaml)
  end

  def to_yaml
    YAML::dump({
      :x => x,
      :y => y,
      :operator => operator
    })
  end

  private
  def cipher
    @cipher ||= self.class.cipher
  end
  def reset_cipher
    @cipher = nil
  end

end