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('');
}
@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