Cómo validar un R.U.T. Chileno
Tags: typescript, chile, npm, tutorial
Published: 2022-04-17 14:25:45

Si eres un desarrollador de software trabajando en Chile tarde o temprano tendrás que implementar algún tipo de validación de un RUT Chileno, ya sea para un formulario de contacto, compras, creación de un usuario o para registrar datos de pago. En este artículo voy a explicar cómo se compone un RUT, cuál es el algoritmo que se usa para obtener un dígito verificador y como implementar su validación en Javascript/Typescript de manera agnóstica a cualquier framework.

## Qué es un R.U.T. 

**El RUT o [Rol Único Tributario](https://es.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario) es un número único para cada persona natural o jurídica en Chile**, similar al [SSN](https://www.ssa.gov/ssnumber/) en Estados Unidos o al [BSN](https://www.government.nl/topics/personal-data/citizen-service-number-bsn) en Holanda. Su función es ayudar a identificar a una persona o ente jurídico de manera estándar a través de diferentes servicios públicos o privados

El formato del RUT tiene la forma `XX.XXX.XXX-Y` en donde `X` es un dígito entre `0-9`, esta sección suele llamarse **"Número" o "Dígitos"** mientras que `Y` puede ser un dígito entre `0-9` o la letra `K`, este último símbolo se llama **"Verificador" o "Dígito verificador"** y este **se calcula usando un algoritmo conocido como "Módulo 11"**.

![Composición de un RUT Chileno mostrando las dos partes; El Número y el Dígito verificador](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd6qyzl5scvqzfa0gwt9.png)

## Módulo 11

Este es un algoritmo para calcular un [Código de Control](https://es.wikipedia.org/wiki/C%C3%B3digo_de_control) los cuales generalmente consisten en uno o más caracteres numéricos o alfabéticos añadidos al dato original. Algunos de los ejemplos de uso frecuentes son los números de identificación personal, códigos de barras, tarjetas de crédito y códigos bancarios.

El cálculo del Módulo 11 es el siguiente:

> 1. A cada dígito del número base se le asigna un factor de chequeo ponderado. Dicho factor será 2 para el dígito menos significativo (el que está más a la derecha) y, en orden, 3, 4, 5, 6, 7 para los siguientes. Si hubiere más de 6 dígitos, la secuencia se repetirá, de modo que el séptimo dígito se multiplicará por 2, el octavo por 3, etcétera.

> 2. Cada dígito del número base se multiplica por el factor de chequeo asignado.

> 3. Se suman los resultados de todas las multiplicaciones.

> 4. Al resultado de la suma se le calcula el módulo 11 (de ahí el nombre del método), es decir, el resto de la división entera entre 11.

> 5. A 11 se le resta el módulo calculado en el punto anterior. Si el resultado de la resta es < 10, dicho resultado es el dígito de control que buscábamos. Si el resultado es 11 el dígito de control es 0 y si el resultado es 10 el dígito de control resultante es 1.

> 6. Específicamente para el cálculo del RUT cuando el resultado del algoritmo es 10 el carácter de control es la letra "K".

Con estos pasos podemos proceder a implementar el algoritmo de la siguiente manera:

```typescript
function calcularVerificador(numero: string) {
  let sum = 0;
  let mul = 2;

  let i = numero.length;
  while (i--) {
    sum = sum + parseInt(numero.charAt(i)) * mul;
    if (mul % 7 === 0) {
      mul = 2;
    } else {
      mul++;
    }
  }

  const res = sum % 11;

  if (res === 0) {
    return '0';
  } else if (res === 1) {
    return 'k';
  }

  return `${11 - res}`;
};
```

## En la práctica

Si bien el algoritmo del Módulo 11 es capaz de calcular el dígito verificador correcto para cualquier set de números **algunas de estas soluciones corresponden a RUTs que no son válidos aunque su dígito verificador es correcto** como por ejemplo `11.111.111-1`, `22.222.222-2` ó `99.999.999-9`. Es por esto que a la hora de implementar una validación en una UI o API no podemos confiar exclusivamente en el resultado de este algoritmo. 

**Para implementar una validación de RUT más confiable tendremos que validar dígito verificador y que el patrón del número a validar no sea invalido usando una o más [Expresiones Regulares](https://en.wikipedia.org/wiki/Regular_expression).**


## Librería de validación en NPM

Ya que el uso del RUT en diversos formularios y APIs online es extremadamente común no es de sorprenderse que [existan varios módulos en NPM](https://www.npmjs.com/search?q=rut) que sean capaces de ofrecer validación de RUT, sin embargo, en mi experiencia estos suelen estar desactualizados y en su mayoría tienen una documentación muy deficiente. Es por esto que decidí crear [mi propio Módulo `@fdograph/rut-utilities`](https://github.com/fdograph/rut-utilities) usando Typescript y creando una [documentación completa](https://github.com/fdograph/rut-utilities/blob/master/README-es.md). 

`@fdograph/rut-utilities` Cuenta con un 100% de test coverage y está mantenido activamente.

## Uso y ejemplos

Para usar esta librería primero debes instalarla como dependencia a tu proyecto.

Con NPM
```bash
$ npm install --save @fdograph/rut-utilities
```
O con Yarn
```bash
$ yarn add @fdograph/rut-utilities
```


### Validación

Para simplemente validar un RUT está la función `validateRut`

```typescript
import { validateRut } from '@fdograph/rut-utilities';

validateRut('18585543-0');
> true
```

Esta función **valida una cadena de RUT usando Módulo 11 y 2 expresiones regulares para evitar falsos positivos en RUTs inválidos.**


### Generación de dígito verificador

Con esta librería también es posible calcular un Dígito Verificador correcto para cualquier número, esto ofrece mas flexibilidad al desarrollador para implementar una validación personalizada

```typescript
import { calculateRutVerifier } from '@fdograph/rut-utilities';

calculateRutVerifier('18585543');
> "0"
```


### Formatear un RUT

`rut-utilites` También exporta una función para dar formato a un RUT (válido o no). Para esto se ofrecen 3 formatos distintos; `DOTS` Ej: `00.000.000k`, `DOTS_DASH` Ej: `00.000.000-k` y `DASH` Ej: `00000000-k`, este último es el formato por defecto.

```typescript
import { formatRut, RutFormat } from '@fdograph/rut-utilities';

formatRut('44.333.222-1');
> '44333222-1'

formatRut('44333222-1', RutFormat.DOTS_DASH);
> '44.333.222-1'

formatRut('44333222-1', RutFormat.DOTS);
> '44.333.2221'
```

## Uso extendido

`rut-utilities` Exporta 11 métodos en total para ofrecer un set de herramientas que te permitan total flexibilidad a la hora de validar, formatear, generar y manipular RUTs. Estos métodos son:

| Método | Retorno | Descripción |
|--|--|--|
|`isRutLike`| `boolean` | Valida si el patrón una cadena corresponde a una cadena con forma de RUT valido |
|`isSuspiciousRut`| `boolean` | Valida si el patrón una cadena corresponde a una cadena con forma de RUT "sospechoso". Ej: `11.111.111-1` |
|`cleanRut`| `string` | Limpia una cadena quitando todos los caracteres que no pertenecen a un RUT válido (`0-9`, `k`, `K`) |
|`getRutDigits`| `string` | Retorna solo el "número` de un RUT sin el dígito verificador |
|`getRutVerifier`| `string` | Retorna solo el dígito verificador de un RUT sin el "número" |
|`calculateRutVerifier`| `string` | Usa el Módulo 11 para calcular el dígito verificador de un set de números |
|`validateRut`| `boolean` | Ejecuta una validación usando el Módulo 11 y expresiones regulares para verificar un RUT válido |
|`formatRut`| `string` | Formatea una cadena con forma de RUT |
|`generateRut`| `string` | Genera un RUT válido al azar |
|`validateRutList`| `Map<string, boolean>` | Ejecuta `validateRut` en una lista de RUTs y retorna un mapa de validación |
|`deconstructRut`| `{digits: string; verifier: string; }` | Retorna un objecto con las partes del RUT dado |


## Gracias!

Muchas gracias por leer este artículo y mucha suerte implementando esta librería en tus proyectos :)

Happy hacking.