Skip to content

Instantly share code, notes, and snippets.

@gaulatti
Last active June 15, 2023 15:12
Show Gist options
  • Save gaulatti/69a24cc199a4253d058c to your computer and use it in GitHub Desktop.
Save gaulatti/69a24cc199a4253d058c to your computer and use it in GitHub Desktop.
HTML5 Chilean RUT Validator
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Validador de RUT HTML5</title>
</head>
<body>
<form>
<input type="text" id="rut" name="rut" required oninput="checkRut(this)" placeholder="Ingrese RUT">
<button type="submit">Validar RUT y Enviar Form</button>
<script src="validarRUT.js"></script>
</form>
</body>
</html>
function checkRut(rut) {
// Despejar Puntos
var valor = rut.value.replace('.','');
// Despejar Guión
valor = valor.replace('-','');
// Aislar Cuerpo y Dígito Verificador
cuerpo = valor.slice(0,-1);
dv = valor.slice(-1).toUpperCase();
// Formatear RUN
rut.value = cuerpo + '-'+ dv
// Si no cumple con el mínimo ej. (n.nnn.nnn)
if(cuerpo.length < 7) { rut.setCustomValidity("RUT Incompleto"); return false;}
// Calcular Dígito Verificador
suma = 0;
multiplo = 2;
// Para cada dígito del Cuerpo
for(i=1;i<=cuerpo.length;i++) {
// Obtener su Producto con el Múltiplo Correspondiente
index = multiplo * valor.charAt(cuerpo.length - i);
// Sumar al Contador General
suma = suma + index;
// Consolidar Múltiplo dentro del rango [2,7]
if(multiplo < 7) { multiplo = multiplo + 1; } else { multiplo = 2; }
}
// Calcular Dígito Verificador en base al Módulo 11
dvEsperado = 11 - (suma % 11);
// Casos Especiales (0 y K)
dv = (dv == 'K')?10:dv;
dv = (dv == 0)?11:dv;
// Validar que el Cuerpo coincide con su Dígito Verificador
if(dvEsperado != dv) { rut.setCustomValidity("RUT Inválido"); return false; }
// Si todo sale bien, eliminar errores (decretar que es válido)
rut.setCustomValidity('');
}
@Acraciel
Copy link

Acraciel commented Aug 14, 2017

Hola!!!, hay otro problema en el inicio cuando estás despejando los puntos, no los despejas todos, sólo a uno.

Lo solucioné poniéndolo de esta manera:

// Despejar Punto1 (Sólo quito el primer punto que encuentre, que sería el punto del millón)
var valor = rut.value.replace('.','');
// Despejar Guión
valor = valor.replace('-','');
//Despejar Punto2 (Quito el punto de los miles que me queda)
valor = valor.replace('.','');

@LeandroBDev
Copy link

LeandroBDev commented Sep 3, 2017

for (i = 0; i < valor.length; i++) {
//valor = valor.replace('.','');
//valor = valor.replace('-','');
valor = valor.replace(/[^0-9\K\k]/g,'');
}

mejor ese, asi cada vez que ingrese "." o "-" lo irá eliminado, aun estoy aprendiendo asi que perdonen la poca ayuda que puedo brindar, pero con lo que subi ira actualizando cada vez el codigo, y además en el input pongan el evento "onchange"

PD: El loop anterior lo cambie por este:
// Despejar Punto1 (Sólo quito el primer punto que encuentre, que sería el punto del millón)
var valor = rut.value.replace('.','');
// Despejar Guión
valor = valor.replace('-','');
//Despejar Punto2 (Quito el punto de los miles que me queda)
valor = valor.replace('.','');

@rodrigoherreral
Copy link

Como mejora para quitar el . y - se puede utilizar:

var valor = rut.replace(/./g, '');
valor = valor.replace(/-/g, '');

De esta manera eliminan todos los puntos y todos los guiones (por si ingresan mas de 1)

@doronshe
Copy link

doronshe commented Dec 1, 2017

consejo usa en el <form onsubmit="return validate(...)">
y añadir un función:
function validate(...) {
return formatRut(...) ||
validateXXX(); // para otras inputs
}

tbn en el input puede usar onblur="formatRut(...)"

El código que uso es lo mismo con algunas detalles deferentes:
function formatRut(rut_input, err_div) {

function formatearMillones(nNmb) {
	var sRes = "";
	for (var j, i = nNmb.length - 1, j = 0; i >= 0; i--, j++)
		sRes = nNmb.charAt(i) + ((j > 0) && (j % 3 == 0) ? ".": "") + sRes;
	return sRes;
}

function validateRut(casilla) {
	var casillaRut = document.getElementById(casilla);
	var valor = casillaRut.value.trim().replace(/[-.\s]/g, '');
	if(valor.length == 0) {
	    return true;
	}
	
	// Aislar Cuerpo y Dígito Verificador
        var cuerpo = valor.slice(0,-1);
	var dv = valor.slice(-1).toUpperCase();
	var hold_dv = dv;

	// Si no cumple con el mínimo ej. (n.nnn.nnn or nn.nnn.nnn)
	if(cuerpo.length < 7 || cuerpo.length > 8) 
		return false;

	// Calcular Dígito Verificador
    var suma = 0;
    var multiplo = 2;
    
    // Para cada dígito del Cuerpo
    for(i=1; i<=cuerpo.length; i++) {
        // Obtener su Producto con el Múltiplo Correspondiente
        index = multiplo * valor.charAt(cuerpo.length - i);
        
        // Sumar al Contador General
        suma = suma + index;
        
        // Consolidar Múltiplo dentro del rango [2,7]
        if(multiplo < 7) { 
        	multiplo = multiplo + 1; 
        } 
        else { 
        	multiplo = 2; 
        }
    }
    
    // Calcular Dígito Verificador en base al Módulo 11
    dvEsperado = 11 - (suma % 11);
    
    // Casos Especiales (0 y K)
    dv = (dv == 'K') ? 10 : dv;
    dv = (dv == 0) ? 11 : dv;
    
    // Validar que el Cuerpo coincide con su Dígito Verificador
	if(dvEsperado != dv) 
		return false; 

	casillaRut.value = formatearMillones(cuerpo) + "-" + hold_dv;
	return true; 
}

if (validateRut(rut_input)) 
{
	// uso un div específicamente para el texto de error con <div id="yyy" ... style="display:none;" ...>
           var err = document.getElementById(err_div);  
	err.style.display = 'none';
	return true; 	
}
else
{
	var err = document.getElementById(err_div);
	err.style.display = 'block';
	return false;
}	

}

asi que usando la función es formatRut('rut', 'yyy'); // el id del input para el rut y el id del div para mostrar errores

@samarti
Copy link

samarti commented May 9, 2018

Para los que usen jQuery Validation Plugin:

function checkRut(rut) {
  rut = String(rut);
  var valor = rut.replace(".", "").replace(".", "");
  valor = valor.replace("-", "");
  cuerpo = valor.slice(0, -1);
  dv = valor.slice(-1).toUpperCase();
  rut = cuerpo + "-" + dv;
  if (cuerpo.length < 7) {
    return false;
  }
  suma = 0;
  multiplo = 2;
  for (i = 1; i <= cuerpo.length; i++) {
    index = multiplo * valor.charAt(cuerpo.length - i);
    suma = suma + index;
    if (multiplo < 7) {
      multiplo = multiplo + 1;
    } else {
      multiplo = 2;
    }
  }
  dvEsperado = 11 - suma % 11;
  dv = dv == "K" ? 10 : dv;
  dv = dv == 0 ? 11 : dv;
  if (dvEsperado != dv) {
    return false;
  }
  return true;
}

$.validator.addMethod("validRut", function(value, element) {
      return checkRut(value);
    }, "Debes ingresar un rut válido");

$('#data-form').validate({
  rules: {
    rut: {
      required: true,
      validRut: true
    }
  }
});

@hanspoo
Copy link

hanspoo commented Sep 29, 2018

Hola,

Muy buena solución, la separe en dos, la moví a ES6, y saqué la conexión con el campo HTML.

function rutEsValido(rut) {
  if (!rut || rut.trim().length < 3) return false;
  const rutLimpio = rut.replace(/[^0-9kK-]/g, "");

  if (rutLimpio.length < 3) return false;

  const split = rutLimpio.split("-");
  if (split.length !== 2) return false;

  const num = parseInt(split[0], 10);
  const dgv = split[1];

  const dvCalc = calculateDV(num);
  return dvCalc === dgv;
}

function calculateDV(rut) {
  const cuerpo = `${rut}`;
  // Calcular Dígito Verificador
  let suma = 0;
  let multiplo = 2;

  // Para cada dígito del Cuerpo
  for (let i = 1; i <= cuerpo.length; i++) {
    // Obtener su Producto con el Múltiplo Correspondiente
    const index = multiplo * cuerpo.charAt(cuerpo.length - i);

    // Sumar al Contador General
    suma += index;

    // Consolidar Múltiplo dentro del rango [2,7]
    if (multiplo < 7) {
      multiplo += 1;
    } else {
      multiplo = 2;
    }
  }

  // Calcular Dígito Verificador en base al Módulo 11
  const dvEsperado = 11 - (suma % 11);
  if (dvEsperado === 10) return "k";
  if (dvEsperado === 11) return "0";
  return `${dvEsperado}`;
}

export { rutEsValido, calculateDV };

Estos son los tests, ruts sacados de http://jqueryrut.sourceforge.net/generador-de-ruts-chilenos-validos.html

import { calculateDV, rutEsValido } from "./utiles/funciones.js";

it("calculateDV kata", () => {
  expect(calculateDV(10864629)).toEqual("2");
  expect(calculateDV(11726111)).toEqual("5");
  expect(calculateDV(13067971)).toEqual("4");
  expect(calculateDV(15223952)).toEqual("1");
  expect(calculateDV(15496120)).toEqual("8");
  expect(calculateDV(16003145)).toEqual("k");
  expect(calculateDV(16158088)).toEqual("0");
  expect(calculateDV(16931829)).toEqual("8");
  expect(calculateDV(17577561)).toEqual("7");
  expect(calculateDV(19791795)).toEqual("4");
  expect(calculateDV(20181773)).toEqual("0");
  expect(calculateDV(20309424)).toEqual("8");
  expect(calculateDV(21705755)).toEqual("8");
  expect(calculateDV(23023518)).toEqual("k");
  expect(calculateDV(23559651)).toEqual("2");
  expect(calculateDV(24261604)).toEqual("9");
  expect(calculateDV(24901269)).toEqual("6");
  expect(calculateDV(6709127)).toEqual("2");
  expect(calculateDV(8139919)).toEqual("0");
  expect(calculateDV(8702020)).toEqual("7");
});

it("RUT validos", () => {
  expect(rutEsValido("10864629-2")).toEqual(true);
  expect(rutEsValido("11726111-5")).toEqual(true);
  expect(rutEsValido("13067971-4")).toEqual(true);
  expect(rutEsValido("15223952-1")).toEqual(true);
  expect(rutEsValido("15496120-8")).toEqual(true);
  expect(rutEsValido("16003145-k")).toEqual(true);
  expect(rutEsValido("16158088-0")).toEqual(true);
  expect(rutEsValido("16931829-8")).toEqual(true);
  expect(rutEsValido("17577561-7")).toEqual(true);
  expect(rutEsValido("19791795-4")).toEqual(true);
  expect(rutEsValido("20181773-0")).toEqual(true);
  expect(rutEsValido("20309424-8")).toEqual(true);
  expect(rutEsValido("21705755-8")).toEqual(true);
  expect(rutEsValido("23023518-k")).toEqual(true);
  expect(rutEsValido("23559651-2")).toEqual(true);
  expect(rutEsValido("24261604-9")).toEqual(true);
  expect(rutEsValido("24901269-6")).toEqual(true);
  expect(rutEsValido("6709127-2")).toEqual(true);
  expect(rutEsValido("8139919-0")).toEqual(true);
  expect(rutEsValido("8702020-7")).toEqual(true);
});

it("RUT invalidos", () => {
  expect(rutEsValido("10864629-1")).toEqual(false);
  expect(rutEsValido("11726111-6")).toEqual(false);
  expect(rutEsValido("13067971-6")).toEqual(false);
  expect(rutEsValido("15223952-2")).toEqual(false);
  expect(rutEsValido("15496120-9")).toEqual(false);
  expect(rutEsValido("16003145-0")).toEqual(false);
  expect(rutEsValido("16158088-1")).toEqual(false);
});

@oscar331331
Copy link

valeria!

@Tox86
Copy link

Tox86 commented Nov 22, 2018

No me funciona en un jsp.

@hanspoo
Copy link

hanspoo commented Jun 21, 2019

No me funciona en un jsp.
Está escrito en ES6, actualmente la mayoría de browsers los soportan. Se puede transpilar con babel a ES5 que ejectua con seguridad en cualquier navegador. Es javascript, en un JSP debe ir dentro de un tag <script>.

@ngeorger
Copy link

Muchas gracias, excelente script y muy adaptable.

@SoyAlex-chama
Copy link

Gracias buen señor, esta filete

@tisoportes
Copy link

Fuera línea de tiempo... pero podria utilizar la implementación que hizo SII, es 100% js

@padawano
Copy link

wena gracias me sirvio arto lo unico que le puse maxlength en el input por si las moscas

@elevenup22
Copy link

Fuera línea de tiempo... pero podria utilizar la implementación que hizo SII, es 100% js

donde se puede ver?

@tisoportes
Copy link

tisoportes commented Mar 17, 2020

Hay que "cachurear" en los scripts asociado al input de ingreso del rut. Es antiguo, pero totalmente funcional y vigente.

@gismodes37
Copy link

Seria interesante que suban el código depurado, código final si errores y funcionando, con tantos cambios y sugerencias de mejoras al final es una ensalada de código y los que no somos muy expertos terminamos abandonando la pagina en busca de algo mas claro y funcional,, lo comento sin el animo de critica si no de una saludable sugerencia, se agradece el aporte.

@ivanvidalsepulveda
Copy link

naaa genio! muchas gracias, lo implemente para un login y creacion de nuevos usuarios, y funcionó a la primera, muchas gracias por tu aporte!

@tisoportes
Copy link

tisoportes commented Sep 18, 2020

// Esto lo usan en sii
// para q reinventar la rueda a menos que sea para optimizar.
// El editor de github se fue a la cresta! no edita correctamente el fuente, sorry nada más que hacer...
// USD 7.5M compra de github y no pueden dejar un editor decente. Incomprensible....

function formatoRut(texto, inputText) {
objRut = document.getElementById(inputText);
var rut_aux = "";
for ( i=0; i < texto.length ; i++ )
if ( texto.charAt(i) != ' ' && texto.charAt(i) != '.' && texto.charAt(i) != '-' )
rut_aux = rut_aux + texto.charAt(i);

largo = rut_aux.length;
if(largo == 0) return false;
if (largo<2) return false;

for (i=0; i < largo ; i++ ) {
    var letra = rut_aux.charAt(i);
    if (!letra.match(/^([0-9]|[kK])$/)) return false;
}
var rut_inv = "";
for ( i=(largo-1),j=0; i>=0; i--,j++ ) rut_inv = rut_inv + rut_aux.charAt(i);

var dtexto = "";
dtexto = dtexto + rut_inv.charAt(0);
dtexto = dtexto + '-';
cnt = 0;

for ( i=1,j=2; i<largo; i++,j++ ){
    if ( cnt == 3 ){
      dtexto = dtexto + '.';
      j++;
     dtexto = dtexto + rut_inv.charAt(i);
     cnt = 1;
  } else {
      dtexto = dtexto + rut_inv.charAt(i);
      cnt++;
  }
}

rut_inv = "";
for ( i=(dtexto.length-1),j=0; i>=0; i--,j++ ) rut_inv = rut_inv + dtexto.charAt(i);

objRut.value = rut_inv.toUpperCase()

}

function validaRut(texto, inputText) {
objRut = document.getElementById(inputText);
var rut_aux = "";
for ( i=0; i < texto.length ; i++ )
if ( texto.charAt(i) != ' ' && texto.charAt(i) != '.' && texto.charAt(i) != '-' )
rut_aux = rut_aux + texto.charAt(i);

largo = rut_aux.length;

if(largo == 0){
    bootstrap_alert.warning('Por favor, ingrese rut y clave.');
   return false;

}

if (largo<2){
bootstrap_alert.warning('Debe ingresar el rut completo');
objRut.focus();
objRut.select();
return false;
}

for (i=0; i < largo ; i++ ) {
var letra = rut_aux.charAt(i);

if (!letra.match(/^([0-9]|[kK])$/)){
    bootstrap_alert.warning('El RUT ingresado no es valido');
    objRut.focus();
    objRut.select();
    return false;
}

}
var rut_inv = "";
for ( i=(largo-1),j=0; i>=0; i--,j++ ) rut_inv = rut_inv + rut_aux.charAt(i);

var dtexto = "";
dtexto = dtexto + rut_inv.charAt(0);
dtexto = dtexto + '-';
cnt = 0;

for ( i=1,j=2; i<largo; i++,j++ ){
if ( cnt == 3 ){
dtexto = dtexto + '.';
j++;
dtexto = dtexto + rut_inv.charAt(i);
cnt = 1;
} else {
dtexto = dtexto + rut_inv.charAt(i);
cnt++;
}
}

rut_inv = "";
for ( i=(dtexto.length-1),j=0; i>=0; i--,j++ ) rut_inv = rut_inv + dtexto.charAt(i);

objRut.value = rut_inv.toUpperCase()
if ( validaDv(rut_aux, inputText) ) return true;

return false;
}

function validaDv( texto, inputText ) {
largo = texto.length;
if ( largo > 2 ){
rut_aux = texto.substring(0, largo - 1);
dv = texto.charAt(largo-1);
} else {
rut_aux = texto.charAt(0);
dv = texto.charAt(largo-1);
}

if (rut_aux.match(/k+/)){
bootstrap_alert.warning('El RUT ingresado no es valido');
document.getElementById(inputText).focus();
document.getElementById(inputText).select();
return false;
}
/elementos a variables/
document.getElementById("rut").value=rut_aux ;
document.getElementById("dv").value=dv;

if ( rut_aux == null || dv == null ) return 0;

var dvr = '0'
var suma = 0
var mult = 2
var res = 0
for (i= rut_aux.length-1 ; i >= 0; i--){
suma = suma + rut_aux.charAt(i) * mult
if (mult == 7)
mult = 2
else
mult++
}
res = suma % 11
if (res==1)
dvr = 'k'
else if (res==0)
dvr = '0'
else{
dvi = 11-res
dvr = dvi + ""
}

if (dvr != dv.toLowerCase()){
bootstrap_alert.warning('D\u00EDgito Verificador incorrecto');
document.getElementById(inputText).focus();
document.getElementById(inputText).select();
return false;
}

return true;
}

@ifyum
Copy link

ifyum commented Nov 9, 2020

alguien de angular 10 que me ayude con este ? https://codesandbox.io/s/numpad-rut-54udb se debe dar el fomarto usando los botones

@Rudi-Ulloa
Copy link

Rudi-Ulloa commented Jan 6, 2021

Hola Gracias por tu Ayuda.

No soy experto en esto solo aficionado, lo estoy implementando en ASP.Net y el rut me lo deja de la siguiente forma 2414385-54
Debería quedar así
24143855-4

.- Codigo Script

<script type="text/javascript">
    function checkRut(rut) {
        var valor = rut.value.replace('.', '');
        valor = valor.replace('-', '');

        cuerpo = valor.slice(0, -1);
        dv = valor.slice(-1).toUpperCase();

        rut.value = cuerpo + '-' + dv
    }
</script> 

.- HTML
<asp:TextBox ID="txt_login" runat="server" Width="150px" ClientIDMode="Static" onkeypress="return checkRut(this)"></asp:TextBox>

Por favor si me pueden ayudar.

@MauricioBarriosB
Copy link

Bueno código! gracias por compartir.... bueno, por si alguien más le sirve, para quitar los puntos y guion ocupe estas exp. regulares:

function checkRut(rut) {
//Despejar Puntos
var valor = rut.replace(/./g, '');
//Despejar Guión
valor = valor.replace(/-/g, '');

@sealsior
Copy link

sealsior commented Dec 5, 2021

Muchas gracias por el código, me sirvió mucho!

@Enzo-Aravena
Copy link

como lo harían si les piden validar también los rut provisorios de extranjeros, los cuales comienzan de los 100 millones, no he podido encontrar la respuesta

@lataacido
Copy link

lataacido commented May 19, 2023 via email

@gaulatti
Copy link
Author

Esta semana voy a refactorizar esto (lo hice hace milenios), qué ha cambiado desde ese entonces en la forma de validarlo aparte del módulo 11?

@ngeorger
Copy link

He visto bastantes módulos sobre todo de WooCommerce que tienen módulos validadores, no sé si son APIs o corren scripots

@PatrickCaneloDigital
Copy link

Segun esta guia, el calculo es bastante simple y aplica para numeros de rut "infinitamente" largos...

https://validarutchile.cl/calcular-digito-verificador.php

la de jumpseller lleva un ejemplo muy compacto (dificil de leer) en javascript

https://jumpseller.cl/support/validar-rut-en-checkout/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment