Problem when validating DNI JavaScript [duplicated]

0

I am starting to learn JavaScript and I had a doubt when validating a DNI.

The regular expression to check that it has 8 numbers and a letter of the alphabet does not work for me.

//Se pide el número completo del DNI (12345678X)
var dni = prompt("Introzuca su número de DNI");
		
//Se separan los números de la letra
var letraDNI = dni.substring(8, 9);
var numDNI = parseInt(dni.substring(0, 8));

//Se calcula la letra correspondiente al número
var letras = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E', 'T'];
var letraCorrecta = letras[numDNI % 23];


//Se comprueba que el formato es válido	
if(numDNI == /\d{8}[a-z A-Z]/){
  numDNI = parseInt(prompt("Introzuca un número válido de DNI"));
}
//Se comprueba si la letra introducida es igual a la calculada
else{

  if(letraDNI.toUpperCase() != letraCorrecta){
    alert("Has introducido una letra incorrecta" + "\n" + "Tu letra debería ser: " + letraCorrecta);
  }
  else{
    alert("Enhorabuena hemos podido validar tu DNI");
  }
}
    
asked by Samuel Reyes 13.10.2017 в 13:21
source

3 answers

2

You have several problems with the use of the regular expression:

//Se comprueba que el formato es válido 
if(numDNI == /\d{8}[a-z A-Z]/){     
    numDNI = parseInt(prompt("Introzuca un número válido de DNI"));
}
  • Comparing a variable with a regular expression using == only serves to tell you if the variable is the same regular expression
  • Even if it works, you're saying that I'll ask again if it's the same, not when it's NOT the same.
  • Even if it worked and you had put! =, you are comparing a number and not a string (you have already removed the letter).
  • When you ask again, you keep only the number and you are not checking again.

The code should look something like the following:

let dni='';
while(!(/^\d{8}[a-zA-Z]$/.test(dni))){
  dni = prompt("Introduzca un número de DNI: 8 números y una letra");
}

//Se separan los números de la letra
var letraDNI = dni.substring(8, 9).toUpperCase();
var numDNI = parseInt(dni.substring(0, 8));

//Se calcula la letra correspondiente al número
var letras = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E', 'T'];
var letraCorrecta = letras[numDNI % 23];

if(letraDNI!= letraCorrecta){
  alert("Has introducido una letra incorrecta\nTu letra debería ser: " + letraCorrecta);
} else {
  alert("Enhorabuena hemos podido validar tu DNI");

}
    
answered by 13.10.2017 в 13:44
2

First of all you should check that the length of the entered data is correct:

if (dni.length !=9)

To verify that the number is correct you should control the exception in the parsimony:

try 
{
  var numDNI = parseInt(dni.substring(0, 8));    
} 
catch (NumberFormatException e) 
{

      //Controlamos la excepcion
}

Proven that the length is correct then if you can look at the value of the letter, otherwise you would have an error in the array dimension: We verify that a letter is the value 9 of the array:

if (Character.isLetter(this.dni.charAt(8) == true)

You already have verified that the format is correct or not by being only numbers and not you should check the format with the code again:

//Se comprueba que el formato es válido 
if(numDNI == /\d{8}[a-z A-Z]/){
    numDNI = parseInt(prompt("Introzuca un número válido de DNI"));
}

Doing all these checks and changes, your code would be like this:

//Se pide el número completo del DNI (12345678X)
var dni = prompt("Introzuca su número de DNI");

//Se comprueba que la dimension del valor introducido es correcto
if (dni.length == 9)
{
    //Se separan los números de la letra
    try 
    {
        var numDNI = parseInt(dni.substring(0, 8)); 
    } 
    catch (NumberFormatException e) 
    {
        //Controlamos la excepcion , el parseo falla. Algun valor no es numero
    }
    //Se calcula la letra correspondiente al número
    var letras = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E', 'T'];
    var letraCorrecta = letras[numDNI % 23];
    //Se comprueba que el ultimo valor es una letra
    if (Character.isLetter(this.dni.charAt(8) == true)
    {
        //Comprobamos que la letra es la calculada
        if(letraDNI.toUpperCase() != letraCorrecta)
        {
            alert("Has introducido una letra incorrecta" + "\n" + "Tu letra debería ser: " + letraCorrecta);
        }
        else
        {
            alert("Enhorabuena hemos podido validar tu DNI");
        }   
    }
    else
    {
    //Error. El valor final no es una letra
    }
}
    
answered by 13.10.2017 в 13:55
0

Without regex

I've got you a couple of functions. They check both the letter and you calculate it and in case there are failures they will warn you.

Take a look, it may be useful.

function comprobardni(dni){
  var numDNI = dni.substring(0, 8);

  if(numDNI.length!=8){
    return comprobardni(prompt("Has Introducido mal el dni:"));
  }else{
    var letra = comprobardni_letra(dni);
    var letracorrecta = calcular_letra(numDNI);
    if(letra===letracorrecta){
      return alert("Enhorabuena hemos podido validar tu DNI");
    }else{
      return comprobardni(prompt("Has introducido una letra incorrecta" + "\n" + "Tu letra debería ser: " + letracorrecta));
    }    
  }
}

function comprobardni_letra(dni){
  var letraDNI = dni.substring(8, 9);
  
  return letraDNI;
}

function calcular_letra(dni){
  var cadena="TRWAGMYFPDXBNJZSQVHLCKET";
  var posicion = dni % 23;
  return cadena.substring(posicion,posicion+1);
}

var dni = comprobardni_numero(prompt("Introzuca su número de DNI"));
    
answered by 13.10.2017 в 14:05