class HkidValidator

Public Class Methods

valid?(number) click to toggle source
# File lib/hkid_validator.rb, line 3
def valid?(number)
  sanitized = number.scan(/\p{Alnum}+/).join.upcase

  return false unless sanitized[-1] =~ /(\d+|A)/

  unless (sanitized.length == 8 &&
          sanitized[0] =~ /[A-Z]/ &&
          sanitized[1...-1] =~ /\d+/) ||
         (sanitized.length == 9 &&
          sanitized[0] =~ /[A-Z]/ &&
          sanitized[1] =~ /[A-Z]/ &&
          sanitized[2...-1] =~ /\d+/)

    return false
  end

  weighted_sum = 324
  queue = sanitized.split('')[0...-1]

  queue[0] = value_at_char(queue[0])
  if sanitized.length == 9
    queue[1] = value_at_char(queue[1])
  end

  while queue.length > 0
    weighted_sum += queue.shift.to_i * (queue.length + 2)
  end

  remainder = weighted_sum % 11

  if remainder == 0
    return sanitized[-1].to_i == 0
  elsif remainder == 1
    return sanitized[-1] == 'A'
  elsif remainder >= 2 && remainder <= 10
    return sanitized[-1].to_i == (11 - remainder)
  end
end

Private Class Methods

value_at_char(char) click to toggle source
# File lib/hkid_validator.rb, line 44
def value_at_char(char)
  (char.ord - 'A'.ord + 10).to_s
end