lib/turkish_id.rb in turkish_id-0.2.2 vs lib/turkish_id.rb in turkish_id-0.3.0

- old
+ new

@@ -1,78 +1,54 @@ require "turkish_id/version" -class String - def digitize - self.split('').map { |s| Integer(s) } - end -end - class TurkishId + attr_reader :id_number, :checksum def initialize(id_number) - begin - @id_number = id_number.digitize # Convert string into array of integers - rescue - @id_number = '' # Suppress error & return false (eventually) - end + @id_number = digitize(id_number) + @checksum = calculate_checksum(@id_number) end - - def core - @id_number.take(9) - end - - - def self.get_checksum(id_core) - - # Calculate the sums of odd and even digits - odds = id_core.values_at(0, 2, 4, 6, 8).reduce(:+) - evens = id_core.values_at(1, 3, 5, 7).reduce(:+) - - # Generate checksum digits - d10 = ((odds * 7) - evens) % 10 - d11 = (id_core.reduce(:+) + d10) % 10 - - [d10, d11] - end - - def self.add_checksum(id_core) - id_core + TurkishId.get_checksum(id_core) - end - def is_valid? - id = @id_number # +1 brevity point + id = @id_number # For brevity - # Early elimination, bad length or first digit + # Early termination, bad length or first digit return false if id.length != 11 || id.first == 0 - # Get checksum digits - d10, d11 = TurkishId.get_checksum(id) + # Calculate checksum if not already calculated + @checksum ||= calculate_checksum(id_number) # Check if the tenth digit matches the algorithm - return false if id[9] != d10 + return false if id[9] != @checksum[0] # Check if the eleventh digit matches the algorithm - return false if id[10] != d11 + return false if id[10] != @checksum[1] true # All conditions met end - def get_relatives(num, direction='up') + private - id = self.core.join.to_i # Our core id as integer + def calculate_checksum(id_number) + # Calculate the sums of odd and even digits + odds = id_number.values_at(0, 2, 4, 6, 8).reduce(:+) + evens = id_number.values_at(1, 3, 5, 7).reduce(:+) - tree = {'up' => 1, 'down' => -1} # + or - based on direction - magic = 131 * 229 * tree[direction] # Eliminates if statement + # Generate checksum digits + d10 = ((odds * 7) - evens) % 10 + d11 = (id_number.take(9).reduce(:+) + d10) % 10 - relatives = [] + # Return checksum + [d10, d11] + rescue + [] # Unable to calculate checksum, initial value remains unchainged + end - num.times do - id += magic # Gives us the next relative - relatives << id # Collecting ids in an array - end + def digitize(id_number) + # Narrow down scope of accepted types + return [] unless [String, Integer, Fixnum].include?(id_number.class) - # Traverse relatives and append checksum digits - relatives.map { |r| TurkishId.add_checksum(r.to_s.digitize).join } + # Convert string of numbers into an array of integers + id_number.to_s.split('').map { |s| Integer(s) } end end