Forum: Rails-ES Validar un CIF, NIF...

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
David A. (Guest)
on 2007-01-19 17:30
(Received via mailing list)
Hola chicos,

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?

Gracias 0:-)

[1]
http://es.wikipedia.org/wiki/C%C3%B3digo_de_Identi...
[2] http://simplelogica.net/logicola
--
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman
Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo

Cuando no hago otra cosa escribo en mildiez.net
Raul M. (Guest)
on 2007-01-19 17:30
(Received via mailing list)
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! :D

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_obtene...
     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í:   http://pastie.caboo.se/32677


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
David A. (Guest)
on 2007-09-26 00:38
(Received via mailing list)
On 1/12/07, Raul M. <removed_email_address@domain.invalid> wrote:
> Wooops, con las prisas olvidé indicar que en la llamada a la función de
> validación aplico un
>
>         candidate_cif.upcase!.gsub!(/\W/,'')

Muchas gracias Raúl, me viene de perlas tanto el algoritmo como el
snippet este para limpiarlo :-)

--
David A., el único desarrollador con una orden de alejamiento de
Jeffrey Zeldman
Simplelogica.net, ahora con un 33,3% más de intromisión en listas de correo

Cuando no hago otra cosa escribo en mildiez.net
Raul M. (Guest)
on 2007-09-26 00:43
(Received via mailing list)
Wooops, con las prisas olvidé indicar que en la llamada a la función de
validación aplico un

  candidate_cif.upcase!.gsub!(/\W/,'')

sobre el CIF a validar, para formatearlo eliminando los caracteres no
alfanuméricos y pasar la/s letra/s a mayúsculas. De esta forma el dato
puede venir en un formato libre (hay gente que separa la letra y los
dígitos con guiones, con espacios...).

Saludos,
   Raul
Raul M. (Guest)
on 2007-09-26 00:47
(Received via mailing list)
Corrigiéndome en voz alta, este código es erróneo:

> Wooops, con las prisas olvidé indicar que en la llamada a la función de
> validación aplico un
>
>   candidate_cif.upcase!.gsub!(/\W/,'')

En contra de lo que yo creía, resulta que upcase! devuelve nil si no ha
realizado ningún cambio, lo que en mi instrucción provoca un error de
ejecución cuando la cadena ya está en mayúsculas.

gsub! se comporta igual: si no hay cambios devuelve nil.
Sebastian D. (Guest)
on 2007-09-26 00:50
(Received via mailing list)
Los metodos ! no son generalmente apropiados para encadenar. Como no
deben retornar un nuevo valor, algunos retornan informacion sobre la
operacion en si misma. Otros retornan self, por lo que si son
encadenables, pero debes leer con detalle la documentacion
This topic is locked and can not be replied to.