lib/turkish_id.rb in turkish_id-0.2.0 vs lib/turkish_id.rb in turkish_id-0.2.1

- old
+ new

@@ -1,33 +1,78 @@ require "turkish_id/version" +class String + def digitize + self.split('').map { |s| Integer(s) } + end +end + class TurkishId def initialize(id_number) begin - # Convert string into array of integers - @id_number = id_number.split('').map { |s| Integer(s) } + @id_number = id_number.digitize # Convert string into array of integers rescue @id_number = '' # Suppress error & return false (eventually) end 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 # Early elimination, bad length or first digit return false if id.length != 11 || id.first == 0 - # Calculate the sums of odd and even digits - odds = id.values_at(0, 2, 4, 6, 8).reduce(:+) - evens = id.values_at(1, 3, 5, 7).reduce(:+) + # Get checksum digits + d10, d11 = TurkishId.get_checksum(id) # Check if the tenth digit matches the algorithm - return false if id[9] != ((odds * 7) - evens) % 10 + return false if id[9] != d10 # Check if the eleventh digit matches the algorithm - return false if id[10] != id[0..9].reduce(:+) % 10 + return false if id[10] != d11 - return true # All conditions met + true # All conditions met + end + + def get_relatives(num, direction='up') + + id = self.core.join.to_i # Our core id as integer + + tree = {'up' => 1, 'down' => -1} # + or - based on direction + magic = 131 * 229 * tree[direction] # Eliminates if statement + + relatives = [] + + num.times do + id += magic # Gives us the next relative + relatives << id # Collecting ids in an array + end + + # Traverse relatives and append checksum digits + relatives.map { |r| TurkishId.add_checksum(r.to_s.digitize).join } end end