module FFaker::SSNSE

def generate_ssn(from, to, gender)

def generate_ssn(from, to, gender)
  birth_date = random_birth_time_between(from, to)
  birth_date_str = birth_date.strftime('%Y%m%d')      # "19800228"
  region = get_random_region_for(gender)              # "413"
  ssn_without_check_digit = birth_date_str + region   # "19800228413"
  check_digit = luhn_check(ssn_without_check_digit)   # "9"
  ssn_without_check_digit + check_digit               # "198002284139"
end

def get_random_region_even

def get_random_region_even
  rand(499) * 2
end

def get_random_region_for(gender)

def get_random_region_for(gender)
  region_number = case gender
                  when 'female' then get_random_region_even
                  when 'male' then get_random_region_odd
  end
  three_character_string(region_number)
end

def get_random_region_odd

def get_random_region_odd
  rand(499) * 2 + 1
end

def luhn_check(number)

http://en.wikipedia.org/wiki/Luhn_algorithm
def luhn_check(number)
  multiplications = []
  number.split(//).each_with_index do |digit, i|
    multiplications << if i.even?
                         digit.to_i * 2
                       else
                         digit.to_i
    end
  end
  sum = 0
  multiplications.each do |num|
    num.to_s.each_byte do |character|
      sum += character.chr.to_i
    end
  end
  control_digit = if sum % 10 == 0
                    0
                  else
                    (sum / 10 + 1) * 10 - sum
  end
  control_digit.to_s
end

def raise_error_on_bad_arguments(from, to, gender)

def raise_error_on_bad_arguments(from, to, gender)
  raise ArgumentError, 'Invalid from argument: from' unless to.is_a? ::Time
  raise ArgumentError, 'Invalid from argument: from' unless from.is_a? ::Time
  raise ArgumentError, 'Invalid argument: from > to' if from > to
  raise ArgumentError, 'Invalid argument: gender' unless GENDERS.include?(gender.to_s)
end

def random_birth_time_between(from = ::Time.local(1940, 1, 1), to = ::Time.now)

def random_birth_time_between(from = ::Time.local(1940, 1, 1), to = ::Time.now)
  ::Time.at(from + rand * (to.to_f - from.to_f))
end

def ssn(opts = {})

def ssn(opts = {})
  from   = opts[:from]   || ::Time.local(1940, 1, 1)
  to     = opts[:to]     || ::Time.now
  gender = (opts[:gender] || fetch_sample(GENDERS)).to_s
  raise_error_on_bad_arguments(from, to, gender)
  generate_ssn(from, to, gender)
end

def three_character_string(number)

def three_character_string(number)
  '%03d' % number
end