Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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('');
}
@ecandiab

This comment has been minimized.

Copy link

@ecandiab ecandiab commented Dec 2, 2014

estimado hay un error en la linea 40, debería ser: v = (dv == 0)?11:dv; si no, no valida los ruts "- 0"

@rotvulpix

This comment has been minimized.

Copy link
Owner Author

@rotvulpix rotvulpix commented Jun 2, 2016

Gracias! Corregido :)

@bsepulveda

This comment has been minimized.

Copy link

@bsepulveda bsepulveda commented Jun 6, 2016

Estimado, esta muy bueno el codigo, pero como seria para agregarle los puntos.

Saludos.

@molinaroca

This comment has been minimized.

Copy link

@molinaroca molinaroca commented Aug 12, 2016

muchas gracias por tremendo aporte!!!

@mefist0000

This comment has been minimized.

Copy link

@mefist0000 mefist0000 commented Dec 3, 2016

muy buen aporte, el mejor valida rut!!!

@novo-root

This comment has been minimized.

Copy link

@novo-root novo-root commented Dec 27, 2016

exceletne aporte amigo faltaria que se agreguen los puntos pero son detalles
estoy muy agradecido :)

@CaneloDigital

This comment has been minimized.

Copy link

@CaneloDigital CaneloDigital commented Apr 14, 2017

Gracias por el aporte.
Para los que piden puntos: OJO: que el script es solo para validar el rut; y, si se fijan, al principio elimina puntos y guiones.

Para añadir puntos y guion vean aqui
https://palabrasalcierre.wordpress.com/2009/11/24/formateo-y-validacion-de-runjava-script/
para añadir ese script tienen que llamarlo cada vez que el usuario vaya modificando el rut y sobreescribir con el resultado lo que se esta ingresando.

@Jimmyjack63

This comment has been minimized.

Copy link

@Jimmyjack63 Jimmyjack63 commented May 2, 2017

Excelente, rotvulpix, aunque soy un ultranovato en JS, y entiendo muy poco. Quisiera saber si alguien me puede ayudar en lo siguiente:
Estoy haciendo un formulario en Adobe acrobat, donde en el campo "RUT" se ingresan los dígitos, sin el dv y sin formato, pues el campo le agrega los puntos. Y el dv se ingresa en el campo "DV".
Lo que quiero es poner un script con la fórmula en el campo "DV", para que una vez ingresados los dígitos, el DV se calcule automáticamente.
Gracias de antemano. Si lo deseas, puedo anexar el archivo pdf con lo que tengo hasta el momento.

@Acraciel

This comment has been minimized.

Copy link

@Acraciel 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

This comment has been minimized.

Copy link

@LeandroBDev 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

This comment has been minimized.

Copy link

@rodrigoherreral rodrigoherreral commented Nov 21, 2017

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

This comment has been minimized.

Copy link

@doronshe 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

This comment has been minimized.

Copy link

@samarti 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

This comment has been minimized.

Copy link

@hanspoo 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

This comment has been minimized.

Copy link

@oscar331331 oscar331331 commented Nov 20, 2018

valeria!

@Tox86

This comment has been minimized.

Copy link

@Tox86 Tox86 commented Nov 22, 2018

No me funciona en un jsp.

@hanspoo

This comment has been minimized.

Copy link

@hanspoo 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

This comment has been minimized.

Copy link

@ngeorger ngeorger commented Aug 12, 2019

Muchas gracias, excelente script y muy adaptable.

@SoyAlex-chama

This comment has been minimized.

Copy link

@SoyAlex-chama SoyAlex-chama commented Sep 27, 2019

Gracias buen señor, esta filete

@tisoportes

This comment has been minimized.

Copy link

@tisoportes tisoportes commented Nov 21, 2019

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

@padawano

This comment has been minimized.

Copy link

@padawano padawano commented Mar 16, 2020

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

@elevenup22

This comment has been minimized.

Copy link

@elevenup22 elevenup22 commented Mar 17, 2020

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

donde se puede ver?

@tisoportes

This comment has been minimized.

Copy link

@tisoportes 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

This comment has been minimized.

Copy link

@gismodes37 gismodes37 commented Jun 7, 2020

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

This comment has been minimized.

Copy link

@ivanvidalsepulveda ivanvidalsepulveda commented Sep 10, 2020

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

This comment has been minimized.

Copy link

@tisoportes 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

This comment has been minimized.

Copy link

@ifyum 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

This comment has been minimized.

Copy link

@Rudi-Ulloa 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

This comment has been minimized.

Copy link

@MauricioBarriosB MauricioBarriosB commented Jul 20, 2021

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, '');

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