class Cfita::CodiceFiscale
Controllo codice fiscale italiano
Constants
- CIFRE
- CONSONANTS
- DISPARI
- MESI
- OMOCODICI
- VOWELS
Attributes
birth_date[R]
birth_place[R]
errors[R]
fiscal_code[R]
sex[R]
Public Class Methods
ccat()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 15 def self.ccat @ccat ||= JSON.parse(open('ccat.json')) end
new( fiscal_code, birth_place: nil, birth_date: nil, name: nil, surname: nil, sex: nil )
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 19 def initialize( fiscal_code, birth_place: nil, birth_date: nil, name: nil, surname: nil, sex: nil ) @fiscal_code = fiscal_code.upcase.strip @birth_place = birth_place&.upcase @birth_date = birth_date @birth_date = Date.parse(birth_date) if birth_date.is_a?(String) @name = name&.parameterize&.upcase @surname = surname&.parameterize&.upcase @sex = sex&.upcase @errors = [] parse end
Public Instance Methods
cf_birth_date()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 64 def cf_birth_date return @cf_birth_date if @cf_birth_date yy = cifre(6..7) day = cifre(9..10) @errors << 'Cifra decina giorno di nascita errata' if day && day > 71 month = MESI.index(@fiscal_code[8]) @errors << 'Mese errato' unless month return unless yy && month && day @cf_birth_date = Date.new(yy2yyyy(yy), month + 1, day % 40) rescue nil end
cf_birth_places()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 58 def cf_birth_places return @cf_birth_places if @cf_birth_places @cf_birth_places = CODICI_CATASTALI[codice_catastale] end
cf_sex()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 46 def cf_sex return @cf_sex if @cf_sex case @fiscal_code[9] when /[0-3LMNP]/ @cf_sex = 'M' when /[4-7QRST]/ @cf_sex = 'F' else @errors << 'Cifra decina giorno di nascita errata' end end
to_s()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 38 def to_s fiscal_code end
valid?()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 42 def valid? errors.empty? end
Private Instance Methods
check_birth_date()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 182 def check_birth_date @errors << 'Data di nascita errata' unless cf_birth_date return if @errors.any? if @birth_date @errors << 'Data di nascita errata' if @birth_date != cf_birth_date else @birth_date = cf_birth_date end end
check_birth_place()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 166 def check_birth_place @errors << "Codice istat #{codice_catastale} non trovato" unless cf_birth_places if @birth_place unless cf_birth_places&.include?(@birth_place) @errors << "Luogo di nascita #{@birth_place} non coerente, al codice catastale #{codice_catastale} corrisponde a #{cf_birth_places.join(' o a ')}" end end end
check_chars()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 149 def check_chars test = @fiscal_code == @fiscal_code[/^[A-Z0-9]*$/] errors << 'Caratteri non ammessi' unless test end
check_checksum()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 154 def check_checksum errors << 'Checksum errato' if checksum != @fiscal_code.last end
check_name()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 108 def check_name return unless @name a, b, c, d = consonants(@name) name_code = ( (d ? [a, c, d] : [a, b, c]).compact.join + vowels(@name).join + 'XXX' )[0..2] errors << "Il nome non corrisponde al codice '#{name_code}'" unless name_code == @fiscal_code[3..5] end
check_sex()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 158 def check_sex if @sex errors << 'Sesso errato' if @sex != cf_sex else @sex = cf_sex end end
check_size()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 144 def check_size size = @fiscal_code.size errors << "Lunghezza errata (#{size})" unless size == 16 end
check_surname()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 121 def check_surname return unless @surname surname_code = ( consonants(@surname).join + vowels(@surname).join + 'XXX' )[0..2] errors << "Il cognome non corrisponde al codice '#{surname_code}'" unless surname_code == @fiscal_code[0..2] end
checksum()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 218 def checksum tot = 0 @fiscal_code[0..14].bytes.first(15).each.with_index do |byte, i| next unless byte byte -= byte < 65 ? 48 : 65 sign = (i % 2).zero? tot += sign ? DISPARI[byte] : byte end (tot % 26 + 65).chr end
cifre(range)
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 193 def cifre(range) result = 0 range.each do |position| char = @fiscal_code[position] value = CIFRE.index(char) @errors << "Carattere '#{char}' errato in posizione #{position}" unless value return nil unless value result *= 10 result += value % 10 end result end
codice_catastale()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 79 def codice_catastale return @codice_catastale if @codice_catastale letter = @fiscal_code[11] numbers = @fiscal_code[12..14] .split(//) .map do |c| i = OMOCODICI.index(c) i ? i.to_s : c end .join letter + numbers end
consonants(word)
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 140 def consonants(word) word.chars.select { |char| char.in? CONSONANTS } end
parse()
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 93 def parse check_size check_chars return if errors.any? check_checksum return if errors.any? check_name check_surname check_birth_date check_birth_place check_sex end
vowels(word)
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 136 def vowels(word) word.chars.select { |char| char.in? VOWELS } end
yy2yyyy(year_as_yy)
click to toggle source
# File lib/cfita/codice_fiscale.rb, line 177 def yy2yyyy(year_as_yy) Date.today.year - (Date.today.year % 100 + 100 - year_as_yy) % 100 end