Esta función javascript está basada en el algoritmo hallado en GoDNI
function validateDNI(dni, cchar) { const numberKeys = [6, 7, 8, 9, 0, 1, 1, 2, 3, 4, 5]; const charKeys = ['K', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']; const factors = [3, 2, 7, 6, 5, 4, 3, 2]; const dniDigits = dni.trim().split('').map(x => parseInt(x, 10)); const sum = dniDigits.reduce((sum, x, i) => { sum += factors[i] * x; console.log(`${i}: ${x} * ${factors[i]} = ${factors[i] * x} => ${sum}`); return sum; }, 0); let keyIndex = 11 - (sum % 11); keyIndex = keyIndex === 11 ? 0 : keyIndex; const control = parseInt(cchar, 10) || cchar.toUpperCase(); console.log(`=> keyIndex: ${keyIndex} => ${numberKeys[keyIndex]} / ${charKeys[keyIndex]}`); if (isNaN(control)) { return control == charKeys[keyIndex]; } else { return control == numberKeys[keyIndex]; } }
Idea
Cada dígito es multiplicado por un factor y agregado a una suma. El residuo de dividir la suma entre 11 se usa para determinar un índice. Ese índice se usa para localizar el dígito o caracter que se usa como control.