Volver al blog
Desarrollo

Calcular Dígito Verificador del RUT en Python: Guía para Desarrolladores

10 min de lectura
Python
RUT
programación
validación
tutorial

Calcular Dígito Verificador del RUT en Python: Guía para Desarrolladores

Python: El lenguaje ideal para procesar RUTs

Python destaca como una excelente opción para trabajar con RUTs chilenos gracias a su sintaxis clara, potentes bibliotecas para procesamiento de datos y versatilidad. Ya sea que necesites validar un solo RUT o procesar millones de ellos, Python ofrece las herramientas perfectas para el trabajo.

Este tutorial te enseñará desde la implementación básica hasta técnicas avanzadas para integrar la validación de RUT en tus proyectos Python, incluyendo aplicaciones web, análisis de datos y automatización.

Implementación básica del algoritmo módulo 11

Función esencial paso a paso:

Python
1def calcular_digito_verificador(rut_numero):
2    """
3    Calcula el dígito verificador de un RUT chileno.
4    
5    Args:
6        rut_numero (int or str): Número del RUT sin dígito verificador
7        
8    Returns:
9        str: Dígito verificador ('0'-'9' o 'K')
10    """
11    # Convertir a string y asegurar 8 dígitos
12    rut_str = str(rut_numero).zfill(8)
13    
14    # Multiplicadores según el algoritmo
15    multiplicadores = [2, 3, 4, 5, 6, 7]
16    
17    # Calcular suma ponderada
18    suma = 0
19    for i, digito in enumerate(reversed(rut_str)):
20        multiplicador = multiplicadores[i % 6]
21        suma += int(digito) * multiplicador
22    
23    # Calcular dígito verificador
24    resto = suma % 11
25    digito_verificador = 11 - resto
26    
27    # Casos especiales
28    if digito_verificador == 11:
29        return '0'
30    elif digito_verificador == 10:
31        return 'K'
32    else:
33        return str(digito_verificador)
34
35# Ejemplos de uso
36print(calcular_digito_verificador(12345678))  # 5
37print(calcular_digito_verificador(11111111))  # 1
38print(calcular_digito_verificador(15834661))  # K

Clase completa para manejo de RUTs

Implementación orientada a objetos:

Python
1import re
2from typing import Optional, Tuple, Union
3
4class RutValidator:
5    """Clase para validar y formatear RUTs chilenos."""
6    
7    def __init__(self):
8        self._cache = {}
9        self._max_cache_size = 1000
10    
11    @staticmethod
12    def limpiar(rut: str) -> str:
13        """
14        Limpia el RUT removiendo puntos, guiones y espacios.
15        
16        Args:
17            rut: RUT en cualquier formato
18            
19        Returns:
20            RUT limpio solo con números y K
21        """
22        return re.sub(r'[.-s]', '', str(rut)).upper()
23    
24    @staticmethod
25    def formatear(rut: str) -> str:
26        """
27        Formatea el RUT con puntos y guión.
28        
29        Args:
30            rut: RUT sin formato
31            
32        Returns:
33            RUT formateado (ej: 12.345.678-9)
34        """
35        rut_limpio = RutValidator.limpiar(rut)
36        
37        if len(rut_limpio) < 2:
38            return rut_limpio
39        
40        # Separar número y dígito verificador
41        numero = rut_limpio[:-1]
42        dv = rut_limpio[-1]
43        
44        # Formatear número con puntos
45        numero_formateado = ''
46        for i, digito in enumerate(reversed(numero)):
47            if i > 0 and i % 3 == 0:
48                numero_formateado = '.' + numero_formateado
49            numero_formateado = digito + numero_formateado
50        
51        return f"{numero_formateado}-{dv}"
52    
53    @staticmethod
54    def calcular_dv(rut_numero: Union[int, str]) -> str:
55        """
56        Calcula el dígito verificador.
57        
58        Args:
59            rut_numero: Número del RUT sin DV
60            
61        Returns:
62            Dígito verificador
63        """
64        # Asegurar string de 8 dígitos
65        rut_str = str(rut_numero).zfill(8)
66        
67        # Calcular suma ponderada
68        suma = sum(
69            int(digito) * (2 + (i % 6))
70            for i, digito in enumerate(reversed(rut_str))
71        )
72        
73        # Obtener dígito verificador
74        dv = 11 - (suma % 11)
75        
76        if dv == 11:
77            return '0'
78        elif dv == 10:
79            return 'K'
80        else:
81            return str(dv)
82    
83    def validar(self, rut: str) -> bool:
84        """
85        Valida un RUT completo.
86        
87        Args:
88            rut: RUT completo con o sin formato
89            
90        Returns:
91            True si es válido, False en caso contrario
92        """
93        rut_limpio = self.limpiar(rut)
94        
95        # Verificar cache
96        if rut_limpio in self._cache:
97            return self._cache[rut_limpio]
98        
99        # Validación
100        resultado = self._validar_sin_cache(rut_limpio)
101        
102        # Actualizar cache
103        self._actualizar_cache(rut_limpio, resultado)
104        
105        return resultado
106    
107    def _validar_sin_cache(self, rut_limpio: str) -> bool:
108        """Realiza la validación sin usar cache."""
109        # Validar largo mínimo
110        if len(rut_limpio) < 2:
111            return False
112        
113        # Separar número y DV
114        numero = rut_limpio[:-1]
115        dv_ingresado = rut_limpio[-1]
116        
117        # Validar que el número contenga solo dígitos
118        if not numero.isdigit():
119            return False
120        
121        # Calcular DV esperado y comparar
122        dv_calculado = self.calcular_dv(numero)
123        return dv_ingresado == dv_calculado
124    
125    def _actualizar_cache(self, rut: str, es_valido: bool):
126        """Actualiza el cache con límite de tamaño."""
127        if len(self._cache) >= self._max_cache_size:
128            # Eliminar el primer elemento (FIFO)
129            self._cache.pop(next(iter(self._cache)))
130        
131        self._cache[rut] = es_valido
132    
133    def extraer_info(self, rut: str) -> Optional[dict]:
134        """
135        Extrae información detallada del RUT.
136        
137        Args:
138            rut: RUT a analizar
139            
140        Returns:
141            Diccionario con información o None si es inválido
142        """
143        if not self.validar(rut):
144            return None
145        
146        rut_limpio = self.limpiar(rut)
147        numero = int(rut_limpio[:-1])
148        
149        return {
150            'numero': numero,
151            'dv': rut_limpio[-1],
152            'formateado': self.formatear(rut_limpio),
153            'sin_formato': rut_limpio,
154            'es_empresa': numero >= 50000000,  # RUTs de empresas generalmente
155            'es_persona': numero < 50000000
156        }
157
158# Uso de la clase
159validator = RutValidator()
160
161# Validar RUTs
162print(validator.validar('12.345.678-5'))  # True
163print(validator.validar('12345678-5'))    # True
164print(validator.validar('12.345.678-9'))  # False
165
166# Formatear RUT
167print(validator.formatear('123456785'))    # 12.345.678-5
168
169# Extraer información
170info = validator.extraer_info('12.345.678-5')
171print(info)
172# {'numero': 12345678, 'dv': '5', 'formateado': '12.345.678-5', ...}

Implementación funcional con decoradores

Estilo Pythónico con decoradores:

Python
1from functools import wraps, lru_cache
2from typing import Callable
3
4def validar_entrada_rut(func: Callable) -> Callable:
5    """Decorador para validar entrada de funciones que reciben RUT."""
6    @wraps(func)
7    def wrapper(rut: str, *args, **kwargs):
8        if not rut or not isinstance(rut, (str, int)):
9            raise ValueError("RUT inválido: debe ser string o entero")
10        return func(rut, *args, **kwargs)
11    return wrapper
12
13def formatear_salida_rut(func: Callable) -> Callable:
14    """Decorador para formatear la salida de funciones que retornan RUT."""
15    @wraps(func)
16    def wrapper(*args, **kwargs):
17        resultado = func(*args, **kwargs)
18        if isinstance(resultado, str) and len(resultado) > 1:
19            return RutValidator.formatear(resultado)
20        return resultado
21    return wrapper
22
23class RutUtils:
24    """Utilidades para RUT con enfoque funcional."""
25    
26    @staticmethod
27    @lru_cache(maxsize=1000)
28    def calcular_dv_cached(rut_numero: str) -> str:
29        """Calcula DV con cache automático."""
30        return RutValidator.calcular_dv(rut_numero)
31    
32    @staticmethod
33    @validar_entrada_rut
34    def es_valido(rut: str) -> bool:
35        """Valida RUT con decorador de validación."""
36        return RutValidator().validar(rut)
37    
38    @staticmethod
39    @validar_entrada_rut
40    @formatear_salida_rut
41    def generar_rut_completo(rut_numero: Union[int, str]) -> str:
42        """Genera RUT completo formateado."""
43        numero_str = str(rut_numero).zfill(8)
44        dv = RutUtils.calcular_dv_cached(numero_str)
45        return f"{numero_str}{dv}"
46
47# Uso con decoradores
48print(RutUtils.es_valido('12.345.678-5'))  # True
49print(RutUtils.generar_rut_completo(12345678))  # 12.345.678-5

Procesamiento masivo con pandas

Validación eficiente de grandes datasets:

Python
1import pandas as pd
2import numpy as np
3from typing import List
4import concurrent.futures
5
6class RutProcessor:
7    """Procesador de RUTs para análisis de datos masivos."""
8    
9    def __init__(self):
10        self.validator = RutValidator()
11    
12    def procesar_dataframe(self, df: pd.DataFrame, columna_rut: str) -> pd.DataFrame:
13        """
14        Procesa un DataFrame agregando columnas de validación.
15        
16        Args:
17            df: DataFrame con RUTs
18            columna_rut: Nombre de la columna con RUTs
19            
20        Returns:
21            DataFrame con columnas adicionales
22        """
23        df = df.copy()
24        
25        # Limpiar RUTs
26        df['rut_limpio'] = df[columna_rut].apply(self.validator.limpiar)
27        
28        # Validar
29        df['rut_valido'] = df['rut_limpio'].apply(self.validator.validar)
30        
31        # Formatear solo los válidos
32        df['rut_formateado'] = df.apply(
33            lambda row: self.validator.formatear(row['rut_limpio']) 
34            if row['rut_valido'] else None,
35            axis=1
36        )
37        
38        # Extraer número y DV
39        df['rut_numero'] = df['rut_limpio'].str[:-1]
40        df['rut_dv'] = df['rut_limpio'].str[-1]
41        
42        return df
43    
44    def procesar_archivo_csv(self, archivo_entrada: str, archivo_salida: str,
45                           columna_rut: str = 'rut') -> dict:
46        """
47        Procesa un archivo CSV con RUTs.
48        
49        Args:
50            archivo_entrada: Path del CSV de entrada
51            archivo_salida: Path del CSV de salida
52            columna_rut: Nombre de la columna con RUTs
53            
54        Returns:
55            Diccionario con estadísticas
56        """
57        # Leer CSV
58        df = pd.read_csv(archivo_entrada)
59        
60        # Procesar
61        df_procesado = self.procesar_dataframe(df, columna_rut)
62        
63        # Guardar resultado
64        df_procesado.to_csv(archivo_salida, index=False)
65        
66        # Estadísticas
67        return {
68            'total_ruts': len(df),
69            'ruts_validos': df_procesado['rut_valido'].sum(),
70            'ruts_invalidos': (~df_procesado['rut_valido']).sum(),
71            'porcentaje_validos': df_procesado['rut_valido'].mean() * 100
72        }
73    
74    def validar_paralelo(self, ruts: List[str], workers: int = 4) -> List[bool]:
75        """
76        Valida RUTs en paralelo para mejor rendimiento.
77        
78        Args:
79            ruts: Lista de RUTs a validar
80            workers: Número de workers paralelos
81            
82        Returns:
83            Lista de booleanos indicando validez
84        """
85        with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
86            return list(executor.map(self.validator.validar, ruts))
87
88# Ejemplo de uso con pandas
89data = {
90    'nombre': ['Juan', 'María', 'Pedro', 'Ana'],
91    'rut': ['12.345.678-5', '11111111-1', '12.345.678-9', '15.834.661-K']
92}
93
94df = pd.DataFrame(data)
95processor = RutProcessor()
96df_procesado = processor.procesar_dataframe(df, 'rut')
97
98print(df_procesado[['nombre', 'rut', 'rut_valido', 'rut_formateado']])

Integración con Django

Modelo y validador personalizado:

Python
1# models.py
2from django.db import models
3from django.core.exceptions import ValidationError
4from django.core.validators import RegexValidator
5
6def validar_rut_chileno(value):
7    """Validador de RUT para Django."""
8    validator = RutValidator()
9    if not validator.validar(value):
10        raise ValidationError(
11            '%(value)s no es un RUT válido',
12            params={'value': value},
13        )
14
15class RutField(models.CharField):
16    """Campo personalizado para RUT chileno."""
17    
18    def __init__(self, *args, **kwargs):
19        kwargs['max_length'] = 12  # XX.XXX.XXX-X
20        kwargs['validators'] = [validar_rut_chileno]
21        super().__init__(*args, **kwargs)
22    
23    def to_python(self, value):
24        """Convierte el valor a formato interno."""
25        if value is None:
26            return value
27        return RutValidator.limpiar(value)
28    
29    def get_prep_value(self, value):
30        """Prepara el valor para guardar en BD."""
31        if value is None:
32            return value
33        return RutValidator.formatear(value)
34
35# Modelo de ejemplo
36class Cliente(models.Model):
37    nombre = models.CharField(max_length=100)
38    rut = RutField(unique=True)
39    email = models.EmailField()
40    
41    def __str__(self):
42        return f"{self.nombre} ({self.rut})"
43
44# forms.py
45from django import forms
46
47class RutWidget(forms.TextInput):
48    """Widget personalizado con formato automático."""
49    
50    def __init__(self, attrs=None):
51        default_attrs = {'placeholder': '12.345.678-9', 'maxlength': '12'}
52        if attrs:
53            default_attrs.update(attrs)
54        super().__init__(default_attrs)
55
56class ClienteForm(forms.ModelForm):
57    class Meta:
58        model = Cliente
59        fields = ['nombre', 'rut', 'email']
60        widgets = {
61            'rut': RutWidget(),
62        }
63    
64    def clean_rut(self):
65        """Limpia y valida el RUT."""
66        rut = self.cleaned_data.get('rut')
67        if rut:
68            validator = RutValidator()
69            if not validator.validar(rut):
70                raise forms.ValidationError('RUT inválido')
71            return validator.formatear(rut)
72        return rut

API REST con FastAPI

Endpoint moderno para validación:

Python
1from fastapi import FastAPI, HTTPException, Query
2from pydantic import BaseModel, validator
3from typing import List, Optional
4
5app = FastAPI(title="RUT Validator API")
6
7class RutRequest(BaseModel):
8    """Modelo para solicitud de validación."""
9    rut: str
10    
11    @validator('rut')
12    def validar_formato_basico(cls, v):
13        if not v or len(v) < 3:
14            raise ValueError('RUT muy corto')
15        return v
16
17class RutResponse(BaseModel):
18    """Modelo para respuesta de validación."""
19    rut_original: str
20    rut_limpio: str
21    rut_formateado: Optional[str]
22    es_valido: bool
23    numero: Optional[int]
24    digito_verificador: Optional[str]
25    mensaje: str
26
27class RutBatchRequest(BaseModel):
28    """Modelo para validación en lote."""
29    ruts: List[str]
30
31# Instancia global del validador
32rut_validator = RutValidator()
33
34@app.post("/validar", response_model=RutResponse)
35async def validar_rut(request: RutRequest):
36    """Valida un RUT individual."""
37    rut = request.rut
38    rut_limpio = rut_validator.limpiar(rut)
39    es_valido = rut_validator.validar(rut)
40    
41    if es_valido:
42        info = rut_validator.extraer_info(rut)
43        return RutResponse(
44            rut_original=rut,
45            rut_limpio=rut_limpio,
46            rut_formateado=info['formateado'],
47            es_valido=True,
48            numero=info['numero'],
49            digito_verificador=info['dv'],
50            mensaje="RUT válido"
51        )
52    else:
53        return RutResponse(
54            rut_original=rut,
55            rut_limpio=rut_limpio,
56            rut_formateado=None,
57            es_valido=False,
58            numero=None,
59            digito_verificador=None,
60            mensaje="RUT inválido"
61        )
62
63@app.post("/validar/lote")
64async def validar_lote(request: RutBatchRequest):
65    """Valida múltiples RUTs."""
66    resultados = []
67    
68    for rut in request.ruts:
69        es_valido = rut_validator.validar(rut)
70        resultados.append({
71            'rut': rut,
72            'valido': es_valido,
73            'formateado': rut_validator.formatear(rut) if es_valido else None
74        })
75    
76    return {
77        'total': len(request.ruts),
78        'validos': sum(1 for r in resultados if r['valido']),
79        'invalidos': sum(1 for r in resultados if not r['valido']),
80        'resultados': resultados
81    }
82
83@app.get("/calcular-dv/{numero}")
84async def calcular_digito_verificador(
85    numero: int = Query(..., ge=1000000, le=99999999)
86):
87    """Calcula el dígito verificador para un número."""
88    dv = rut_validator.calcular_dv(numero)
89    return {
90        'numero': numero,
91        'digito_verificador': dv,
92        'rut_completo': rut_validator.formatear(f"{numero}{dv}")
93    }
94
95# Ejecutar con: uvicorn main:app --reload

Testing completo con pytest

Suite de pruebas profesional:

Python
1import pytest
2from rut_validator import RutValidator
3
4class TestRutValidator:
5    """Tests para el validador de RUT."""
6    
7    @pytest.fixture
8    def validator(self):
9        """Fixture para crear instancia del validador."""
10        return RutValidator()
11    
12    @pytest.mark.parametrize("rut,esperado", [
13        ("12.345.678-5", True),
14        ("12345678-5", True),
15        ("123456785", True),
16        ("11.111.111-1", True),
17        ("15.834.661-K", True),
18        ("15834661-k", True),  # k minúscula
19    ])
20    def test_validar_ruts_correctos(self, validator, rut, esperado):
21        """Test para RUTs válidos."""
22        assert validator.validar(rut) == esperado
23    
24    @pytest.mark.parametrize("rut", [
25        "12.345.678-9",
26        "11.111.111-2",
27        "00000000-0",
28        "abc123",
29        "",
30        None,
31    ])
32    def test_validar_ruts_incorrectos(self, validator, rut):
33        """Test para RUTs inválidos."""
34        assert validator.validar(str(rut) if rut else "") == False
35    
36    @pytest.mark.parametrize("numero,dv_esperado", [
37        (12345678, "5"),
38        (11111111, "1"),
39        (22222222, "2"),
40        (15834660, "0"),
41        (15834661, "K"),
42    ])
43    def test_calcular_digito_verificador(self, validator, numero, dv_esperado):
44        """Test para cálculo de dígito verificador."""
45        assert validator.calcular_dv(numero) == dv_esperado
46    
47    def test_formatear_rut(self, validator):
48        """Test para formateo de RUT."""
49        assert validator.formatear("123456785") == "12.345.678-5"
50        assert validator.formatear("11111111") == "1.111.111-1"
51        assert validator.formatear("1234567K") == "1.234.567-K"
52    
53    def test_limpiar_rut(self, validator):
54        """Test para limpieza de RUT."""
55        assert validator.limpiar("12.345.678-5") == "123456785"
56        assert validator.limpiar("12 345 678-5") == "123456785"
57        assert validator.limpiar("12345678-k") == "12345678K"
58    
59    def test_extraer_info(self, validator):
60        """Test para extracción de información."""
61        info = validator.extraer_info("12.345.678-5")
62        assert info is not None
63        assert info['numero'] == 12345678
64        assert info['dv'] == '5'
65        assert info['formateado'] == '12.345.678-5'
66        assert info['es_persona'] == True
67        assert info['es_empresa'] == False
68    
69    def test_cache_funciona(self, validator):
70        """Test para verificar funcionamiento del cache."""
71        rut = "12.345.678-5"
72        
73        # Primera validación
74        resultado1 = validator.validar(rut)
75        
76        # Segunda validación (debería usar cache)
77        resultado2 = validator.validar(rut)
78        
79        assert resultado1 == resultado2
80        assert validator.limpiar(rut) in validator._cache
81
82# Ejecutar con: pytest test_rut_validator.py -v

CLI: Herramienta de línea de comandos

Script ejecutable con argparse:

Python
1#!/usr/bin/env python3
2"""
3RUT Validator CLI
4Herramienta de línea de comandos para validar RUTs chilenos.
5"""
6
7import argparse
8import sys
9import csv
10from typing import List
11
12def main():
13    parser = argparse.ArgumentParser(
14        description='Validador de RUT chileno',
15        epilog='Ejemplos: %(prog)s -v 12.345.678-5'
16    )
17    
18    parser.add_argument(
19        '-v', '--validar',
20        help='Valida un RUT',
21        metavar='RUT'
22    )
23    
24    parser.add_argument(
25        '-c', '--calcular',
26        help='Calcula dígito verificador',
27        metavar='NUMERO',
28        type=int
29    )
30    
31    parser.add_argument(
32        '-f', '--formatear',
33        help='Formatea un RUT',
34        metavar='RUT'
35    )
36    
37    parser.add_argument(
38        '-a', '--archivo',
39        help='Procesa archivo CSV',
40        metavar='ARCHIVO'
41    )
42    
43    parser.add_argument(
44        '-o', '--output',
45        help='Archivo de salida para CSV',
46        metavar='ARCHIVO'
47    )
48    
49    args = parser.parse_args()
50    
51    validator = RutValidator()
52    
53    if args.validar:
54        es_valido = validator.validar(args.validar)
55        if es_valido:
56            print(f"✓ RUT válido: {validator.formatear(args.validar)}")
57        else:
58            print(f"✗ RUT inválido: {args.validar}")
59            sys.exit(1)
60    
61    elif args.calcular:
62        dv = validator.calcular_dv(args.calcular)
63        rut_completo = f"{args.calcular}{dv}"
64        print(f"Número: {args.calcular}")
65        print(f"Dígito verificador: {dv}")
66        print(f"RUT completo: {validator.formatear(rut_completo)}")
67    
68    elif args.formatear:
69        try:
70            formateado = validator.formatear(args.formatear)
71            print(formateado)
72        except Exception as e:
73            print(f"Error al formatear: {e}")
74            sys.exit(1)
75    
76    elif args.archivo:
77        processor = RutProcessor()
78        output = args.output or 'validados.csv'
79        
80        try:
81            stats = processor.procesar_archivo_csv(
82                args.archivo, 
83                output,
84                'rut'
85            )
86            
87            print(f"Archivo procesado: {args.archivo}")
88            print(f"Total RUTs: {stats['total_ruts']}")
89            print(f"Válidos: {stats['ruts_validos']} ({stats['porcentaje_validos']:.1f}%)")
90            print(f"Inválidos: {stats['ruts_invalidos']}")
91            print(f"Resultado guardado en: {output}")
92            
93        except Exception as e:
94            print(f"Error procesando archivo: {e}")
95            sys.exit(1)
96    
97    else:
98        parser.print_help()
99
100if __name__ == '__main__':
101    main()
102
103# Hacer ejecutable: chmod +x rut_validator.py
104# Usar: ./rut_validator.py -v 12.345.678-5

Optimización y buenas prácticas

Versión optimizada con numpy:

Python
1import numpy as np
2from numba import jit
3
4class RutValidatorOptimized:
5    """Validador optimizado para procesamiento masivo."""
6    
7    @staticmethod
8    @jit(nopython=True)
9    def calcular_dv_numba(rut_numero: int) -> int:
10        """Cálculo optimizado con Numba."""
11        multiplicadores = np.array([2, 3, 4, 5, 6, 7])
12        suma = 0
13        i = 0
14        
15        while rut_numero > 0:
16            digito = rut_numero % 10
17            multiplicador = multiplicadores[i % 6]
18            suma += digito * multiplicador
19            rut_numero //= 10
20            i += 1
21        
22        dv = 11 - (suma % 11)
23        return 0 if dv == 11 else 10 if dv == 10 else dv
24    
25    @staticmethod
26    def validar_numpy_batch(ruts: np.ndarray) -> np.ndarray:
27        """
28        Valida un array de RUTs usando NumPy.
29        
30        Args:
31            ruts: Array de números de RUT (sin DV)
32            
33        Returns:
34            Array de dígitos verificadores
35        """
36        # Vectorizar la función
37        calc_dv_vec = np.vectorize(RutValidatorOptimized.calcular_dv_numba)
38        return calc_dv_vec(ruts)
39
40# Benchmark
41import time
42
43# Generar RUTs de prueba
44ruts_prueba = np.random.randint(1000000, 25000000, size=100000)
45
46# Método optimizado
47start = time.time()
48dvs = RutValidatorOptimized.validar_numpy_batch(ruts_prueba)
49print(f"NumPy + Numba: {time.time() - start:.3f} segundos")
50
51# Método tradicional
52validator = RutValidator()
53start = time.time()
54dvs_tradicional = [validator.calcular_dv(rut) for rut in ruts_prueba]
55print(f"Método tradicional: {time.time() - start:.3f} segundos")

Conclusión

Python ofrece un ecosistema rico para trabajar con RUTs chilenos, desde implementaciones simples hasta soluciones empresariales complejas. Las opciones presentadas cubren diversos escenarios:

  • Scripts simples: Para validaciones rápidas y automatización
  • Aplicaciones web: Integración con Django y FastAPI
  • Análisis de datos: Procesamiento masivo con pandas
  • Alto rendimiento: Optimización con NumPy y Numba

La flexibilidad de Python permite adaptar estas soluciones a cualquier necesidad, manteniendo siempre código limpio, testeable y eficiente.

---

Recursos adicionales

  • Python.org: Documentación oficial y mejores prácticas
  • PyPI: Busca paquetes existentes como python-rut
  • Real Python: Tutoriales avanzados de Python
  • GitHub: Ejemplos y proyectos open source de validación RUT

Sobre el autor

CF

Catalina Fuentes

Desarrolladora Backend

Programadora backend con amor por Python y el código limpio. Practica yoga y es mentora en comunidades tech.