Validando CIF en Java (definitivo)

Hasta ahora hemos utilizado la librería de la AEAT para la validación de CIF, pero desgraciadamente, esto no incluye los últimos cambios realizados en el cálculo del CIF por lo que hay que desarrollar una función para que lo haga. A continuación, la versión definitiva de la función de validación del CIF en JAVA:

 private static boolean validarCIF(String cif) {

 if (cif != null) {
 final String cifUP = cif.toUpperCase();

 if ("ABCDEFGHJKLMNPQRSUVW".indexOf(cifUP.charAt(0)) == -1) {
 return false;
 }

 final Pattern mask = Pattern
 .compile("[ABCDEFGHJKLMNPQRSUVW][0-9]{7}[A-Z[0-9]]{1}");
 final Matcher matcher = mask.matcher(cifUP);


 if (!matcher.matches()) {
 return false;
 }

 final char primerCar = cifUP.charAt(0);
 final char ultimoCar = cifUP.charAt(cifUP.length() - 1);


 TipoUltCaracter tipUltCar;

 if (primerCar == 'P' || primerCar == 'Q' || primerCar == 'S' || primerCar == 'K' || primerCar == 'W') {
 tipUltCar = TipoUltCaracter.LETRA;
 if (!(ultimoCar >= 'A' && ultimoCar <= 'Z')) {
 return false;
 }

 } else if (primerCar == 'A' || primerCar == 'B' || primerCar == 'E'
 || primerCar == 'H') {
 tipUltCar = TipoUltCaracter.NUMERO;
 if (!(ultimoCar >= '0' && ultimoCar <= '9')) {
 return false;
 }

 } else {
 tipUltCar = TipoUltCaracter.AMBOS;
 }


 final String digitos = cifUP.substring(1, cifUP.length() - 1);

 Integer sumaPares = 0;
 for (int i = 1; i <= digitos.length() - 1; i = i + 2) {
 sumaPares += Integer.parseInt(digitos.substring(i, i + 1));
 }

 Integer sumaImpares = 0;
 for (int i = 0; i <= digitos.length() - 1; i = i + 2) {
 Integer cal = Integer.parseInt(digitos.substring(i, i + 1)) * 2;
 if (cal.toString().length() > 1) {
 cal = Integer.parseInt(cal.toString().substring(0, 1))
 + Integer.parseInt(cal.toString().substring(1, 2));
 }
 sumaImpares += cal;
 }

 final Integer total = sumaPares + sumaImpares;

 Integer numControl = 10 - (total % 10);
 
 /*if (numControl == 10){
 numControl = 0;
 }*/
 int pos = numControl == 10? 0:numControl; 

 final char carControl = "JABCDEFGHI".charAt(pos);

 if (tipUltCar == TipoUltCaracter.NUMERO) {

 final Integer ultCar = Integer.parseInt(Character
 .toString(ultimoCar));
 if (pos != ultCar.intValue()) {
 
 return false;
 }

 } else if (tipUltCar == TipoUltCaracter.LETRA) {
 if (carControl != ultimoCar) {
 return false;
 }

 } else { 
 // find all occurrences forward
 Integer ultCar = -1;

 ultCar = "JABCDEFGHI".indexOf(ultimoCar);
 
 if (ultCar < 0){
 ultCar = Integer.parseInt(Character.toString(ultimoCar));
 if (pos != ultCar.intValue()) {
 return false;
 }
 }
 if ((pos != ultCar.intValue()) && (carControl != ultimoCar)) {
 return false;
 }
 }
 return true;
 }
 return false;
 }

Recordad que pueden surgir variaciones, pero a día de hoy es correcta esta implementación.

Implementado a partir de los datos de la Wikipedia

Entrada anterior

https://fjrodriguezg.wordpress.com/2015/02/24/validando-nif-en-java-con-la-lbreria-de-aeat-los-nuevos-certificados-de-la-fnmt-y-sorpresa/

Eliminado el siguiente trozo de código pues ya hay CIFs que empiezan por 87 en Madrid:

final Integer codigoProv = Integer.parseInt(cifUP.substring(1, 3));
 final int codigo = codigoProv.intValue();

 if ((codigo == 67) || (codigo == 69) 
 || (codigo >= 87 && codigo <= 90)) {
 return false;
 }

9 comentarios en “Validando CIF en Java (definitivo)

  1. Hola.
    Soy estudiante de Telecomunicaciones y para una práctica de POO debemos realizar un método que compruebe el CIF. Tengo la librería de la AEAT, pero el profesor nos recomienda integrar el código en una de nuestras clases de Java. ¿Podría utilizar su implementación?
    Muchas gracias por su atención y por compartir sus conocimientos con nosotros.

    ¡Un saludo!

    Me gusta

    • Hola Alex.
      La librería de AEAT no tiene en cuenta todos los CIF al estar desactualizada.
      De hecho, te diría que quitases esta parte del código:
      final Integer codigoProv = Integer.parseInt(cifUP.substring(1, 3));
      final int codigo = codigoProv.intValue();
      if ((codigo == 67) || (codigo == 69)
      || (codigo >= 87 && codigo <= 90)) {
      return false;
      }
      Motivo: Ya hay CIFs que empiezan por 87 en Madrid.
      Y por supuesto, puedes utilizarla 🙂

      Me gusta

      • ¡Muchas gracias!
        Si te parece correcto, te acreditaré en el método, poniendo este blog como fuente del código ( la finalidad de la práctica no es la implementación de esta función 😉 ) .

        Y aprovecho para felicitarte por este blog; está genial con información útil y muy bien redactada.

        Me gusta

      • Te agradezco la mención 🙂
        Me alegro de que sea útil la información. La idea del blog es que otras personas no pierdan el tiempo con los mismos problemas y de paso, de recordatorio para mí.

        Me gusta

Deja un comentario