Anexo:Implementaciones para algoritmo de rut

A continuación se presentan diversas implementaciones de algoritmos validadores de RUN/RUT en algunos de los más populares lenguajes de programación:

Fórmula MS ExcelEditar

Si el RUT está en la celda A1, esta fórmula entrega el dígito verificador para cualquier número entre 0 y 999.999.999:

=EXTRAE("123456789K0";11-RESIDUO(MMULT({2\3\4\5\6\7\2\3\4};TRUNCAR(RESIDUO(A1;10^FILA($1:$9))/10^(FILA($1:$9)-1);0)*{1;1;1;1;1;1;1;1;1});11);1)

ACL Analytics Editar

COMMENT
SE CREARÁ UN CAMPO DE TEXTO CON EL RUT EN FORMATO "0000000", tomando el valor del campo "CAMPO_RUT"

CAMPO_RUT="AQUI_COLOCA_EL_RUT"

DEFINE FIELD ENT_DV_STRING COMPUTED LAST("0000000000"+ALLTRIM(%CAMPO_RUT%);9)

DEFINE FIELD ENT_DV_NUMERO COMPUTED 11 - MOD( (VALUE(SUBSTR(ENT_DV_STRING;9;1);0)*2 + VALUE(SUBSTR(ENT_DV_STRING;8;1);0)*3 + VALUE(SUBSTR(ENT_DV_STRING;7;1);0)*4 + VALUE(SUBSTR(ENT_DV_STRING;6;1);0)*5 + VALUE(SUBSTR(ENT_DV_STRING;5;1);0)*6 + VALUE(SUBSTR(ENT_DV_STRING;4;1);0)*7 + VALUE(SUBSTR(ENT_DV_STRING;3;1);0)*2 + VALUE(SUBSTR(ENT_DV_STRING;2;1);0)*3 + VALUE(SUBSTR(ENT_DV_STRING;1;1);0)*4);11)

DEFINE FIELD ENT_DV_FINAL   COMPUTED 

 "K" IF ENT_DV_NUMERO=10
 "0" IF ENT_DV_NUMERO=11
SUBSTR( ALLTRIM(STRING(ENT_DV_NUMERO;1));1;1)

Asterisk dialplanEditar

[rut]
;Llegar a este contexto por medio de la aplicacion Gosub
;El ARG1 es el rut sin puntos ni guion
;El ARG2 es el valor de K, por defecto es 0
;Las variables de salida son resultado que asume el valor "Correcto" si la comprobacion es verdadera y el Valor "Falso" si la comprobacion es incorrecta, y RUN que entrega

exten => s,1,Set(LOCAL(rut)=${ARG1})
	same => n,Set(dv=${MATH(${LOCAL(rut)}%10,int)})
	same => n,Set(rutsdv=${MATH(${rut}/10,int)})
	same => n,Set(largo=${LEN(${rutsdv})})
	same => n,Set(RUN=)
	same => n,Set(contador=0)
	same => n,Set(var_z=0)
	same => n,While($[${contador}<${largo}])
	same => n,Set(contador=${INC(contador)})
	same => n,Set(var_m=$[${contador}-1])
	same => n,Set(var_n0=${MATH(${SET(var_n=${MATH(10^${contador},int)})}/10,int)})
	same => n,Set(serie=${MATH(${var_m}/6,int)})
	same => n,Set(var_p=${MATH(${MATH(${rutsdv}%${var_n},int)}/${var_n0},int)})
	same => n,Set(RUN=${var_p}${RUN})
	same => n,ExecIf($[${MATH(${contador}%3,int)}=0]?Set(RUN=.${RUN}))
	same => n,Set(var_q0=${MATH(${serie}*6,int)})
	same => n,Set(var_q1=${MATH(${contador}+1,int)})
	same => n,Set(var_q=${MATH(${var_q1}-${var_q0},int)})
	same => n,Set(var_w=${MATH(${var_p}*${var_q},int)})
	same => n,Set(var_z=${MATH(${var_z}+${var_w}))})
	same => n,EndWhile
	same => n,Set(var_a=${MATH(${var_z}%11)})
	same => n,Set(var_x=${MATH(11-${var_a})})
	same => n,Set(LOCAL(valork)=${IF($[${EXISTS(${ARG2})}=1]?${ARG2}:0)})
	same => n,ExecIF($[${var_x}=10]?Set(var_x=${LOCAL(valork)}))
	same => n,Set(resultado=${IF($[${var_x}=${dv}]?"Correcto":"Falso")})
	same => n,Set(RUN=${RUN}-${dv})
	same => n,Noop(${resultado})
	same => n,Return()

C# Editar

private string digitoVerificador(int rut)
{
      int Digito;
      int Contador;
      int Multiplo;
      int Acumulador;
      string RutDigito;

      Contador = 2;
      Acumulador = 0;

      while (rut != 0)
      {
      Multiplo = (rut % 10) * Contador;
      Acumulador = Acumulador + Multiplo;
      rut = rut/10;
      Contador = Contador + 1;
      if (Contador == 8)
            {
             Contador = 2;
            }

      }

      Digito = 11 - (Acumulador % 11);
      RutDigito = Digito.ToString().Trim();
      if (Digito == 10 )
      {
            RutDigito = "K";
      }
      if (Digito == 11)
      {
            RutDigito = "0";
      }
      return (RutDigito);
      }

      }
 }

/// Una versión mas corta
public static string Dv(string r)
{
    int suma = 0;
    for (int x = r.Length - 1; x >= 0; x--)
        suma += int.Parse(char.IsDigit(r[x])?r[x].ToString():"0") * (((r.Length - (x + 1)) % 6) + 2);
    int numericDigito = (11 - suma % 11);
    string digito = numericDigito == 11 ? "0" : numericDigito == 10 ? "K" : numericDigito.ToString();
    return digito;
}

/// Una versión funcional
public static char GenerarDV (int num)
{
    return "0K987654321" [  
        Enumerable.Range (0, (int) Math.Floor (Math.Log10 (num)) + 2)  
            .Select (i =>  
                ((i % 6) + 2) *  
                ((num / (int) Math.Pow (10, i)) % 10))  
            .Sum () % 11];
}

C++Editar

char digito_verificador_rut(unsigned rut)
{
   unsigned sum = 0, factor = 2;
   while(rut)
   {
       sum += (rut%10)*factor;
       rut/=10;
       factor = factor==7 ? 2 : factor+1;
   }
   const unsigned res = 11 - sum%11;

   return res == 11? '0' : res == 10? 'k' : res+'0';
}

GolangEditar

func RutValidate(rut int) string {
	var sum = 0
	var factor = 2
	for ; rut != 0; rut /= 10 {
		sum += rut % 10 * factor
		if factor == 7 {
			factor = 2
		} else {
			factor++
		}
	}

	if val := 11 - (sum %11) ; val == 11 {
		return "0"
	} else if val == 10 {
		return "K"
	} else {
		return strconv.Itoa(val)
	}
}

HaskellEditar

import Data.Char (intToDigit)

isValid :: Int -> Char -> Bool
isValid n v = computeVerifier n == v

computeVerifier :: Int -> Char
computeVerifier x = case checkDigit of
                      0 -> 'K'
                      d -> intToDigit (d - 1)
  where checkDigit = modulo11 x 0 1 

modulo11 :: Int -> Int -> Int -> Int
modulo11 0 _ s = s
modulo11 n m s = modulo11 n' m' s'
  where n' = div n 10
        m' = m + 1
        s' = mod (s + mod n 10 * (9 - mod m 6)) 11

-- > isValid 30686957 '0'
-- False
-- > isValid 30686957 '4'
-- True

Java Editar

    public static boolean ValidarRut(int rut, char dv) {
        int m = 0, s = 1;
        for (; rut != 0; rut /= 10) {
            s = (s + rut % 10 * (9 - m++ % 6)) % 11;
        }
        return dv == (char) (s != 0 ? s + 47 : 75);
    }

JavaScriptEditar

  dv = function(T) {
     var M=0,S=1;
     for(;T;T=Math.floor(T/10))
        S=(S+T%10*(9-M++%6))%11;
     return S?S-1:'K';
  }
  alert('El digito verificador del rut ingresado es '+
         dv(prompt('Ingrese rut para mostrar su digito verificador:')));

Objective-CEditar

//validation with parse logic from RUT string format XX.XXX.XXX-Y
+ (BOOL)validRUT:(NSString*)rut{
    
    //remove any dots or signs from RUT string with format XX.XXX.XXX-Y
    //http://es.wikipedia.org/wiki/Rol_%C3%9Anico_Tributario
    
    rut = [rut stringByReplacingOccurrencesOfString:@"." withString:@""];
    rut = [rut stringByReplacingOccurrencesOfString:@"-" withString:@""];
    
    //get rut validator digit (Y)
    char dv = [rut characterAtIndex:[rut length]-1];
    NSLog(@"DV: %c", dv);
    
    //get rut numeric value from (XX.XXX.XXX)
    int rutnumber = [[rut substringToIndex:[rut length]-1] integerValue];
    NSLog(@"RUT NUMBER: %d", rutnumber);
    
    //check valid RUT number (XX.XXX.XXX) with validator digit (Y)
    return [self validRUT:rutnumber with:dv];
}

//algorithm module 11 based on the Java version
+ (BOOL)validRUT:(int)rut with:(char)dv
{
    //to accept 'k' lowercase to avoid issues with "K" clients
    dv = (dv == 'k')?'K':dv;
    NSLog(@"RUT DV: %c", dv);

    int m = 0, s = 1;
    for (; rut != 0; rut /= 10) {
        s = (s + rut % 10 * (9 - m++ % 6)) % 11;
    }
    
    //generate DV to check
    char dvcheck = (char) (s != 0 ? s + 47 : 75);

    NSLog(@"RUT DV: %c", dv);
    NSLog(@"GEN DV: %c", dvcheck);
    
    return dv == dvcheck;
}

Perl 6Editar

    #!/usr/bin/perl6
    my ($RUT, @RUT, $digito);

    $RUT = @*ARGS;                       # leemos el argumento pasado al programa
    @RUT = $RUT.comb().reverse;          # lo pasamos a array y le damos la vuelta

    $digito = [+](@RUT <<*>> (2 ... 7)); # cálculo del dígito verificador
    $digito = 11 - $digito % 11;
    $digito = ( 0 ... 9, 'K', 0 )[$digito];

    say "$RUT-$digito";                  # salida

PHPEditar

  function dv($r){
     $s=1;
     for($m=0;$r!=0;$r/=10)
         $s=($s+$r%10*(9-$m++%6))%11;
     echo 'El digito verificador del rut ingresado es ',chr($s?$s+47:75);
  }

Pl/pgsql de PostgreSql Editar

CREATE OR REPLACE FUNCTION sp_rut_cl(
          rut VARCHAR
          ) RETURNS CHARACTER(1)
   AS
$BODY$
DECLARE
  rec record;
  suma INTEGER := 0;
  serie INTEGER := 2;
  resto INTEGER;
  dv CHARACTER(1);
BEGIN
  --raise notice 'rut: %',rut;
  if (rut is null) then
    return null;
  end if;
  rut := btrim(rut);
  rut := replace(rut, '.', '');
  if (rut is null) then
    return null;
  end if;
  rut := btrim(rut);
  for rec in select * from (
              select substring(rut from i for 1)::char as bit
              from generate_series(length(rut),1,-1) as i
              --where bit = '1'
            ) q1 LOOP
            --raise notice '1';
            --raise notice 'rec.bit: %',rec.bit;
            --raise notice '2';
            if rec.bit is not null and rec.bit ~ '[0-9]+' then
		suma := suma + rec.bit::INTEGER * serie;
            end if;
            --raise notice '3';
            --raise notice 'serie: %',serie;
            if serie = 7 then 
              serie := 1;
            end if;
            serie := serie + 1;
  end loop;
  --raise notice 'suma: %',suma;
  resto := 11 - suma % 11;
  --raise notice 'resto: %',resto;
  dv := case resto when 11 then '0' when 10 then 'K' else resto::CHARACTER end;
  return dv;
end;
$BODY$ LANGUAGE 'plpgsql' volatile;

PSeIntEditar

Proceso digito_verificador
        Definir rut, a1, pa, c, sum, di, digi Como Enteros;
        Escribir "Este programa define su dígito verificador ";
  Escribir "Ingrese su rut sin el dígito verificador ";
  Leer rut;
  pa<-rut;
  c<-2;
  sum<-0;
  Mientras rut>0 Hacer
    a1<-rut%10;
    rut<-trunc(rut/10);
    sum<-sum+(a1*c);
    c<-c+1;
    Si c=8 Entonces
      c<-2;
    FinSi
  FinMientras
  di<-sum%11;
  digi<-11-di;
  Si digi=11 Entonces
    Escribir "El dígito verificador es 0";
    Escribir pa,"-0";   
  Sino
    Si digi=10 Entonces
      Escribir "El dígito verificador es K";
      Escribir pa,"-K";
    Sino
      Escribir "El dígito verificador es ",digi;
      Escribir pa,"-",digi;
    FinSi
  FinSi
FinProceso

Python Editar

def digito_verificador(rut):
    value = 11 - sum([ int(a)*int(b)  for a,b in zip(str(rut).zfill(8), '32765432')])%11
    return {10: 'K', 11: '0'}.get(value, str(value))

REditar

dv <- function(rut){
  rut = as.character(rut)
  x = as.numeric(rev(strsplit(rut,NULL)[[1]]))
  Multiplo = rep(2:7,length.out=length(x))
  y = sum(x*Multiplo)
  z = 11 - y + floor(y/11)*11
  key = c(1:11)
  val = c(1:9,"k",0)
  dv = val[match(z, key)]
  return(dv)
}

Ruby Editar

def digito_verificador(rut)
  [*0..9,'K'][rut.to_s.reverse.chars.inject([0,0]){|(i,a),n|[i+1,a-n.to_i*(i%6+2)]}[1]%11]
end

Scala Editar

def getDv(x: String) : Char = {
    var rut = x.toInt
    var m = -1
    var s = 1
    while (rut != 0) {
        m = m + 1
        s = (s + rut % 10 * (9 - m % 6)) % 11;
        rut = rut / 10
    }
    val dv = if (s != 0) s + 47 else 75
    dv.toChar
}

def getDv2(x: String) : Char = { 
    val rut= x.toList
    val modulus:Int= 11 - (((rut.map(i=>i.toInt-48)) zip rut.indices.map(i=>i%6+2).reverse.toList).map(i=>i._1*i._2).foldLeft(0)((a,b)=>a+b)%11)
    if(modulus==11) '0' else if (modulus == 10 ) 'K' else (modulus+48).toChar
}

Swift 3 Editar

enum RutValidator {
    public static func isValid(rut: String, verifier: String) -> Bool {
        return verifier.uppercased() == verifierCharacter(rut: rut)
    }

    public static func verifierCharacter(rut: String) -> String {
        let digits = rut.characters.flatMap { Int(String($0)) }
        let indexedDigits = Array(digits.reversed().enumerated())
        let verifierCode = mod11(enumeratedDigits: indexedDigits)
        return verifierCharacter(code: verifierCode)
    }
    
    public static let K = "K"

    private static func makeFactor(index: Int) -> Int {
        return 2 + index % 6
    }

    private static func mod11(enumeratedDigits: [(offset: Int, element: Int)]) -> Int {
        let sum = enumeratedDigits.reduce(0) { (m, e) in
            return m + e.element * makeFactor(index: e.offset)
        }
        let code = 11 - sum % 11
        return code % 11
    }

    private static func verifierCharacter(code: Int) -> String {
        switch code {
        case 0...9: return String(code)
        case 10: return K
        default: fatalError("Invalid numeric code generated by mod11 algorithm")
        }
    }
}

// Ejemplos de uso
RutValidator.isValid(rut: "12.345.678", verifier: "5") // true
RutValidator.verifierCharacter(rut: "23456789") == "6" // true
RutValidator.isValid(rut: "66.456.789", verifier: "k") // true
RutValidator.isValid(rut: "66.456.789", verifier: "K") // true
RutValidator.verifierCharacter(rut: "66.456.789") == RutValidator.K // true

Transact-SQLEditar

CREATE FUNCTION RutDigito
   (@Rut as integer)
RETURNS varchar(1)
AS
BEGIN
     declare @Digito as integer
     declare @Contador as integer
     declare @Multiplo as integer
     declare @Acumulador as integer
     declare @retorno as varchar(1)

     set @Contador = 2
     set @Acumulador = 0

     WHILE @Rut <> 0
     BEGIN
          set @Multiplo = (@Rut % 10) * @Contador
          set @Acumulador = @Acumulador + @Multiplo
          set @Rut = @Rut / 10
          set @Contador = @Contador + 1                
          If @Contador > 7  set @Contador = 2
     END

     set @Digito = 11 - (@Acumulador % 11)

     select @retorno = case when @Digito = 10 then 'K' 
                              when @Digito = 11 then '0'
                              else cast(@Digito as varchar(1))
                       end

      return @retorno

END

Visual Basic MS ExcelEditar

Public Function RutDigito(ByVal Rut As Long) As String
    Dim Digito      As Integer
    Dim Contador    As Integer
    Dim Multiplo    As Integer
    Dim Acumulador  As Integer
    Contador = 2
    Acumulador = 0
    While Rut <> 0
      Multiplo = (Rut Mod 10) * Contador
      Acumulador = Acumulador + Multiplo
      Rut = Rut \ 10
      Contador = Contador + 1
      If Contador > 7 Then
        Contador = 2
      End If
    Wend
    Digito = 11 - (Acumulador Mod 11)
    RutDigito = CStr(Digito)
    If Digito = 10 Then RutDigito = "K"
    If Digito = 11 Then RutDigito = "0"
  End Function

JuliaEditar

function rut(rut::Int64)
digitos = digits(rut)
for i = 1:length(z)
    digitos[i]*=((i-1)%6 + 2)
end
resultado =  11 - sum(digitos)%11
if resultado == 11
    return 'K'
elseif resultado == 10
    return '0'
else 
    return "$resultado"[1]
end
end