Skip to main content

Parte del ecosistema Tooltician — validación y formato de RUT chileno, sin dependencias externas.

Parte de Tooltician

PyPI version Python Downloads Licencia Estilo de código Integración continua

Rutificador

Biblioteca Python para validar, calcular y formatear el Rol Único Tributario (RUT) chileno. Sin dependencias externas, tipado estático completo, y soporte para procesamiento por lotes, streaming, CLI, e integraciones opcionales con Pydantic v2, FastAPI, pandas y polars.

from rutificador import Rut

rut = Rut("12.345.678-5")
print(rut.formatear(separador_miles=True))  # 12.345.678-5

resultado = Rut.parse("12.345.678-9")
print(resultado.estado, resultado.codigo_error)  # invalido DV_DISCORDANTE

Tabla de Contenidos


Características

  • Cero dependencias base — solo estándar de Python. Instalación liviana y segura.
  • Validación completa — formato, dígito verificador, longitud configurable, modos de rigor.
  • Formateo flexible — separador de miles, mayúsculas en DV, separador personalizado.
  • Streaming y lotes — archivos de millones de líneas sin cargar todo en memoria.
  • Procesamiento en paralelo — motor por procesos (CPU-bound) o hilos (I/O-bound).
  • Parseo seguro — Rut.parse() nunca lanza excepción, siempre retorna resultado estructurado.
  • Enmascaramiento y tokenización — protege datos sensibles en logs, exports o pantallas.
  • Motor de sugerencias — corrección fuzzy de errores tipográficos comunes.
  • Integraciones opcionales — Pydantic v2, FastAPI, pandas, polars.
  • Tipado estático — py.typed (PEP 561), cobertura mypy completa.
  • CLI profesional — salida en text, JSON, JSONL, CSV y XML.

Instalación

pip install rutificador

Con extras:

pip install rutificador[pydantic]   # Pydantic v2
pip install rutificador[fastapi]    # FastAPI + Pydantic
pip install rutificador[pandas]     # pandas accessor
pip install rutificador[polars]     # polars namespace
pip install rutificador[full]       # todo lo anterior

Uso básico

Validación y parseo

from rutificador import Rut

# Creación directa — valida en el constructor (lanza excepción si es inválido)
rut = Rut("12.345.678-5")

# Parseo seguro — nunca lanza excepción, siempre retorna resultado estructurado
resultado = Rut.parse("12.345.678-5")
print(resultado.estado)  # valido
print(resultado.normalizado)  # 12345678-5

resultado = Rut.parse("12.345.678-9")
print(resultado.estado)  # invalido
print(resultado.codigo_error)  # DV_DISCORDANTE

# Capturar error en validación directa
from rutificador.exceptions import ErrorValidacionRut

try:
    Rut("12.345.678-9")
except ErrorValidacionRut as e:
    print(e.codigo_error)  # DV_DISCORDANTE

Formateo

rut = Rut("12345678-5")

print(rut.formatear())  # 12345678-5
print(rut.formatear(separador_miles=True))  # 12.345.678-5
print(rut.formatear(mayusculas=True))  # 12345678-5
print(rut.formatear(separador_miles=True, mayusculas=True))  # 12.345.678-5

# Con DV en 'k'
rut_k = Rut("12345670-k")
print(rut_k.formatear(separador_miles=True, mayusculas=True))  # 12.345.670-K

Cálculo del dígito verificador

from rutificador import calcular_digito_verificador

dv = calcular_digito_verificador("12345678")
print(dv)  # 5

Enmascaramiento

from rutificador import Rut

# Ofuscar parcialmente
print(Rut.enmascarar("12.345.678-5", mantener=3, caracter="X"))  # XXXXX678-5
print(Rut.enmascarar("12.345.678-5", mantener=4))  # ****5678-5

# Tokenización
print(Rut.enmascarar("12.345.678-5", modo="token", clave="mi-clave"))  # tok_abc123...

Sugerencias y autocorrección

from rutificador import Rut

# Sugerir correcciones para un RUT con error tipográfico
sugerencias = Rut.sugerir("12.345.687-5")
print(sugerencias)  # ['12345678-5', ...]

# Autocorrección inteligente
mejor_opcion = Rut.mejorar("12a345678-k")
print(mejor_opcion)  # 12345678-5

Línea de comandos

# Validar desde un archivo
rutificador validar ruts.txt

# Validar desde stdin
cat ruts.txt | rutificador validar

# Formatear con separador de miles
rutificador formatear ruts.txt --separador-miles --mayusculas

# Enmascarar datos sensibles
rutificador enmascarar ruts.txt --mantener 3

# Salida estructurada
rutificador validar ruts.txt --format jsonl > resultados.jsonl

# Procesamiento paralelo
rutificador validar ruts_pesados.txt --paralelo --format csv

# Autocorreccion + sugerencias
rutificador validar sucia_db.txt --mejorar --sugerir

# Gate de calidad en CI (falla solo si más del 1 % es inválido)
rutificador validar ruts.txt --max-tasa-error 0.01 --quiet || echo "gate fallido"

# Informacion del sistema
rutificador info

Comandos

Comando Descripción
validar Valida RUTs desde archivo o stdin
formatear Valida y formatea RUTs con opciones de salida
enmascarar Ofusca/tokeniza RUTs para proteger datos sensibles
info Muestra versión, entorno y funcionalidades
  • Gate de calidad — validar --max-tasa-error 0.01 retorna 0 si la tasa de inválidos está dentro del umbral y 2 si lo supera (detalle en docs/guia/cli.md).

Formatos de salida

Formato Descripción
text Legible por humanos con resumen de auditoría en stderr
json Array JSON estándar (OOM-Safe via streaming)
jsonl Una línea por registro — ideal para Big Data
csv Hoja de cálculo con cabecera
xml Estructura incremental para integraciones legacy

Procesamiento por lotes

from rutificador import ProcesadorLotesRut

ruts = ["12.345.678-5", "98.765.432-1", "1-9"]
procesador = ProcesadorLotesRut()

resultado = procesador.validar_lista_ruts(ruts)
print(len(resultado.detalles_validos))  # 2
print(len(resultado.detalles_invalidos))  # 1

# Formatear a JSON, CSV o XML
csv = procesador.formatear_lista_ruts(ruts, formato="csv")
print(csv)
# rut
# 12345678-5
# ...

# Paralelismo explícito
procesador = ProcesadorLotesRut(motor_paralelo="process")
resultado = procesador.validar_lista_ruts(ruts, paralelo=True)

Streaming (archivos grandes)

from rutificador import validar_flujo_ruts, formatear_flujo_ruts

# Validar millones de RUTs sin cargar todo en memoria
ruts = (linea.strip() for linea in open("muy_grande.txt"))
for es_valido, resultado in validar_flujo_ruts(ruts):
    if es_valido:
        print(resultado.valor)

Integraciones

Pydantic v2

pip install rutificador[pydantic]
from pydantic import BaseModel
from rutificador.contrib.pydantic import RutStr, rut_str_annotated


class Usuario(BaseModel):
    rut: RutStr


u = Usuario(rut="12.345.678-5")
print(u.rut)  # 12345678-5

# Formato específico
RutConPuntos = rut_str_annotated(formato="miles-con-guion")


class UsuarioV2(BaseModel):
    rut: RutConPuntos


u2 = UsuarioV2(rut="12.345.678-5")
print(u2.rut)  # 12.345.678-5

FastAPI

pip install rutificador[fastapi]
from fastapi import FastAPI, Depends
from rutificador import Rut
from rutificador.contrib.fastapi import parametro_rut

app = FastAPI()


@app.get("/usuario/{rut}")
def obtener_usuario(rut: Rut = Depends(parametro_rut)):
    return {"rut_normalizado": str(rut), "dv": rut.digito_verificador}

Los errores de validación retornan 422 Unprocessable Entity con código estructurado (DV_DISCORDANTE, CARACTERES_INVALIDOS, etc.).

pandas

pip install rutificador[pandas]
import pandas as pd
import rutificador.pandas  # activa el accessor .rut

s = pd.Series(["12.345.678-5", "12.345.678-9", "invalid"])
print(s.rut.es_valido())
# 0     True
# 1    False
# 2    False

print(s.rut.formatear(formato="miles"))
# 0    12.345.678-5
# 1          None
# 2          None

polars

pip install rutificador[polars]
import polars as pl
import rutificador.polars  # activa el namespace .rut

df = pl.DataFrame({"rut": ["12.345.678-5", "12.345.678-9", "invalid"]})
print(df.with_columns(pl.col("rut").rut.es_valido()))

Validación avanzada

from rutificador import Rut, ValidadorRut
from rutificador.config import RigorValidacion, ConfiguracionRut

# Modo flexible: tolera espacios, guiones extra, etc.
validador = ValidadorRut(modo=RigorValidacion.FLEXIBLE)
rut = Rut("12 345 678-5", validador=validador)

# Configuración avanzada
config = ConfiguracionRut(max_digitos=10)
validador = ValidadorRut(configuracion=config)

# Normalización con rigor flexible
normalizado, errores, advertencias = Rut.normalizar(
    "12 345 678-5", modo=RigorValidacion.FLEXIBLE
)
print(normalizado)  # 12345678-5

Referencia de errores

Todos los errores tienen códigos estables y severidad explícita:

from rutificador import Rut

res = Rut.parse("12..345")
for err in res.errores:
    print(err.codigo, err.severidad, err.hint)

Errores

Código Descripción
ERROR_TIPO Tipo inválido
RUT_VACIO Entrada vacía
CARACTERES_INVALIDOS Caracteres no permitidos
FORMATO_PUNTOS Separadores de miles inválidos
FORMATO_GUION Guión inválido
LONGITUD_MINIMA Longitud mínima no alcanzada
LONGITUD_MAXIMA Longitud máxima excedida
DV_INVALIDO Dígito verificador inválido
DV_DISCORDANTE DV no coincide
ESTADO_ENMASCARADO Enmascarado en estado no válido
CLAVE_TOKEN_REQUERIDA Falta clave de tokenización

Advertencias

Código Descripción
NORMALIZACION_ESPACIOS Espacios eliminados
NORMALIZACION_GUION Guión normalizado
NORMALIZACION_PUNTOS Puntos eliminados
NORMALIZACION_DV DV en minúscula
CEROS_IZQUIERDA Ceros a la izquierda eliminados

Registro y depuración

import logging
from rutificador import configurar_registro

configurar_registro(level=logging.DEBUG)

Con handler personalizado:

import logging
import json
from rutificador import configurar_registro


class JsonFormatter(logging.Formatter):
    def format(self, record):
        return json.dumps({"nivel": record.levelname, "mensaje": record.getMessage()})


handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
configurar_registro(level=logging.INFO, handler=handler)

API de referencia

Metadatos de validación

from rutificador import ProcesadorLotesRut

procesador = ProcesadorLotesRut()
resultado = procesador.validar_lista_ruts(["12.345.678-5"], paralelo=False)

detalle = resultado.detalles_validos[0]
print(detalle.valor)  # 12345678-5
print(detalle.validador_modo)  # estricto/flexible
print(detalle.duracion)  # segundos consumidos en la validacion

# Errores con codigo estructurado
resultado_error = procesador.validar_lista_ruts(["12345678-9"])
problema = resultado_error.ruts_invalidos[0]
print(problema.rut, problema.codigo, problema.mensaje)

Evaluar rendimiento

from rutificador import evaluar_rendimiento

resultados = evaluar_rendimiento(num_ruts=1000)
print(resultados["tasa_exito"])

Formateador personalizado

from rutificador.formatter import FormateadorRut, FabricaFormateadorRut


class FormateadorLista(FormateadorRut):
    def formatear(self, ruts):
        return ",".join(ruts)


FabricaFormateadorRut.registrar_formateador("lista", FormateadorLista)

Desarrollo

Entorno

git clone https://github.com/cortega26/rutificador.git
cd rutificador
python -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
pip install -e .
pre-commit install

Calidad

pytest -W error::DeprecationWarning   # Tests sin deprecaciones
mypy rutificador/                     # Tipado estatico
ruff check .                          # Lint
ruff format . --check                 # Formato
bandit -r rutificador/                # Seguridad
deptry rutificador                    # Coherencia de dependencias
pre-commit validate-config            # Configuracion de hooks
cyclonedx-py environment -o sbom.json # SBOM de desarrollo/CI

Las contribuciones son bienvenidas. Revisa CONTRIBUTING.md para las directrices completas.

Alcance

Rutificador no verifica la existencia del RUT en registros oficiales ni realiza enriquecimiento de identidad. Su alcance es la validación sintáctica, normalización y formateo según las reglas locales del RUT chileno.


Licencia

MIT © Carlos Ortega González. Ver LICENSE.

Créditos

Este proyecto se inspiró en rut-chile de gevalenz.


Built and maintained by Carlos Ortega — automation, data systems, and web technical hygiene consulting. Portfolio and services: tooltician.com.

Parte del ecosistema Tooltician — validación y formato de RUT chileno, sin dependencias externas.

Metadata

Release files for rutificador 2.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rutificador 2.2.1
File Size Uploaded
rutificador-2.2.1.tar.gz 43.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rutificador 2.2.1
File Interpreter ABI Platform
rutificador-2.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 93.4 kB

Release files / rutificador-2.2.1.tar.gz

Download URL rutificador-2.2.1.tar.gz
Size 43.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7c58dbf2a67950cbe6b2b41f32f0d88ebd513f1323de849d0158dcf97ee34eaa
BLAKE2b-256 checksum
How to use checksums
61d85c9b680291d05391bba7acb1afbf79673cdf41a2eb290ae0c99bd9c5554d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / rutificador-2.2.1-py3-none-any.whl

Download URL rutificador-2.2.1-py3-none-any.whl
Size 49.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e40fd83845d8da5024ad7e87910b98c8a3322e76f97748213b173a394cbc5042
BLAKE2b-256 checksum
How to use checksums
ff1538f8713e73b803c3136c09523de308019dbf4c1ea1232f2353bcfe15dd36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release history Release notifications | RSS feed

2.3.0

2 release files

This release

2.2.1 This release

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.9.0

2 release files

1.6.1

2 release files

1.5.8

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.4.5

2 release files

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.24

2 release files

1.0.23

2 release files

1.0.22

2 release files

1.0.21

2 release files

1.0.20

2 release files

1.0.19

2 release files

1.0.18

2 release files

1.0.17

2 release files

1.0.16

2 release files

1.0.15

2 release files

1.0.14

2 release files

1.0.13

2 release files

1.0.12

2 release files

1.0.11

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.0

2 release files

0.2.26

2 release files

0.2.25

2 release files

0.2.24

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page