Created
July 27, 2016 12:49
-
-
Save mberlanda/ccaf80ac8800a4188a0b6fe9b14524de to your computer and use it in GitHub Desktop.
Partita IVA (Italian VAT identification number) checksum calculation and validation in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://it.wikipedia.org/wiki/Partita_IVA#Struttura_della_partita_IVA | |
module ChecksumCalculation | |
def calculate(ary) | |
(10 - t(ary)) % 10 | |
end | |
private | |
def t(ary) | |
odd, even = separate_odd_even(ary) | |
(x(odd) + y(even)) % 10 | |
end | |
def x(odd) | |
odd.inject(0){ |sum, x| sum += x } | |
end | |
def y(even) | |
even.inject(0){ |sum, x| sum += process_even(x)} | |
end | |
def separate_odd_even(ary) | |
hash = Hash[*ary] | |
return hash.keys, hash.values | |
end | |
def process_even(n) | |
n*2 > 9 ? n*2 - 9 : n*2 | |
end | |
end | |
module ChecksumValidation | |
def validate(ary) | |
(10 - t(ary)) % 10 | |
end | |
private | |
def t(ary) | |
odd, even = separate_odd_even(ary) | |
(x(odd) + y(even)+ z(even)) % 10 | |
end | |
def x(odd) | |
odd.inject(0){ |sum, x| sum += x } | |
end | |
def y(even) | |
even.inject(0){ |sum, x| sum += x*2} | |
end | |
def z(even) | |
even.count{|x| x >= 5} | |
end | |
def separate_odd_even(ary) | |
hash = Hash[*ary] | |
return hash.keys, hash.values | |
end | |
end | |
class VatNumber | |
extend ChecksumValidation | |
class << self | |
def is_valid?(vat_number) | |
return false if !check_length(vat_number) | |
validate_checksum(vat_number) | |
end | |
def check_length(vat_number) | |
vat_number.size == 11 | |
end | |
def validate_checksum(vat_number) | |
ary = vat_number.split('').map(&:to_i) | |
check_value = ary.pop | |
validate(ary) == check_value | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment