Hola David!
Iba a ponerme a escribir un método para validar un CIF[1], pero el
compi del al lado[2] me ha dicho que sois über-majos y que seguro que
alguno lo ha escrito alguna vez… ¿es eso cierto?
Lo de que somos über-majos es ciertísimo, claro!
En cuanto a la validación que pides, casualmente me ha tocado
implementarla hoy (tampoco la he encontrado en la red). Aquí va:
def add_digits_from_int(n)
digits = str_to_int_array(n.to_s)
digits.inject(0) { |acum, n| acum + n }
end
def str_to_int_array(str)
(0…(str.length-1)).inject([]) { |result, pos| result <<
str[pos,1].to_i }
end
def is_a_valid_cif?(candidate)
return false unless candidate.length == 9
# We also accept NIFs, NIF validation algoritm taken from:
#
http://es.wikipedia.org/wiki/Algoritmo_para_obtener_la_letra_del_NIF
if candidate.match(/\D(\d{8})/)
nif_letter = candidate[0,1]
nif_digits = candidate[1,8]
elsif candidate.match(/(\d{8})\D/)
nif_letter = candidate[-1, 1]
nif_digits = candidate[0,8]
end
nif_addition = nif_digits.to_i % 23
return true if nif_letter && nif_digits &&
‘TRWAGMYFPDXBNJZSQVHLCKE’[nif_addition,1] == nif_letter
# CIF validation algorithm taken from:
# http://club.telepolis.com/jagar1/Ccif.htm
return false unless "ABCDEFGHNPQS".include? candidate[0,1]
central_digits = str_to_int_array(candidate[1,7])
a = [1,3,5].inject(0) { |acum, pos| central_digits[pos] + acum }
b = [0,2,4,6].inject(0) { |acum, pos| acum +
add_digits_from_int(central_digits[pos] * 2) }
candidate_digit = 10 - ( (a+b) % 10)
candidate_letter = "JABCDEFGHI"[candidate_digit,1]
control_digit = candidate[8,1]
control_digit == candidate_digit.to_s || control_digit ==
candidate_letter
end
Como no sé si se verá bien, también la dejo
aquí: Parked at Loopia
DISCLAIMER:
La he terminado hace un rato y tengo un hambre que no veo, así que
aún no la he sometido a demasiadas pruebas y seguramente el código apesta:
sugerencias, críticas, bugs y demás feedback será siempre bienvenido.
Eso sí, después de la cena
Saludos,
Raul