Autor Tema: Buén validador de RUT en PHP  (Leído 15198 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado WHK

  • 吴阿卡
  • Administrador
  • Aportador
  • *****
  • Mensajes: 555
  • Karma: +15/-3
  • Coder
    • Yahoo Instant Messenger - yan_uniko_102
    • Ver Perfil
    • WHK
    • Email
Buén validador de RUT en PHP
« : febrero 27, 2012, 02:22:35 pm »
Para los que no sepan el RUT es el número de identidad personal.

Estaba dandole un vistazo a una montonera de blogs y foros sobre cómo validar el RUT desdephp pero de los que si funcionaban bién no realizaba la verificación al 100% ya que tenias que ingresar solo los números, otro validava como verdadero si ingresabas solamente un cero, en fin.

Asi que hize mi propio validador de RUT, lo estoy usando en un sitio WEB y anda de lujo :D

Código: php [Seleccionar]
<?php
echo (esRut('0') ? 1 : 0);
echo (esRut('111111111') ? 1 : 0);
echo (esRut('21383755') ? 1 : 0);
echo (esRut('213837559') ? 1 : 0);
echo (esRut('21.383.755-9') ? 1 : 0);
echo (esRut('21,383,755-9') ? 1 : 0);
echo ' Formateado: '.esRut('213837559');
 
// Devuelve: 000111 Formateado 21.383.755-9
 
function esRut($r = false){
    if((!$r) or (is_array($r)))
        return false; /* Hace falta el rut */
 
    if(!$r = preg_replace('|[^0-9kK]|i', '', $r))
        return false; /* Era código basura */
 
    if(!((strlen($r) == 8) or (strlen($r) == 9)))
        return false; /* La cantidad de carácteres no es válida. */
 
    $v = strtoupper(substr($r, -1));
    if(!$r = substr($r, 0, -1))
        return false;
 
    if(!((int)$r > 0))
        return false; /* No es un valor numérico */
 
    $x = 2; $s = 0;
    for($i = (strlen($r) - 1); $i >= 0; $i--){
        if($x > 7)
            $x = 2;
        $s += ($r[$i] * $x);
        $x++;
    }
    $dv=11-($s % 11);
    if($dv == 10)
        $dv = 'K';
    if($dv == 11)
        $dv = '0';
    if($dv == $v)
        return number_format($r, 0, '', '.').'-'.$v; /* Formatea el RUT */
    return false;
}

Bueno bonito y barato, resistente a bugs y problemas con el formateo de carácteres ya que te lo devuelve 100% compuesto y si no es válido te debuelve un false.

Acá hay un buén generador de ruts válidos en JavaScript:

http://joaquinnunez.cl/jQueryRutPlugin/generador-de-ruts-chilenos-validos.html

A veces cuando tratamos de ingresar a una red de internet del metro o lugares así nos piden el rut, cuando queremos hacer una pregunta o sugerencia en alguna página web del gobierno nos solicitan hasta el color de ropa interior que llevamos, asi que con este generador podemos darles datos al azar y llenar su base de datos de ruts basura sin que se metan en nuestra vida privada.
Mi WEB - The Hacktivism is not a crime - Si no lo hago yo, que lo hagan otros -
Si has encontrado útil este articulo recuerda que puedes ayudarnos con tu donación voluntaria la cual ayudará al staff y a la mantención del foro.

Lucas Cardemil Villegas

  • Visitante
Re:Buén validador de RUT en PHP
« Respuesta #1 : diciembre 16, 2015, 02:44:30 pm »
mi rut pasa al colocarlo sin raya 18356694-6

Gonzalo

  • Visitante
Clase validación y generación de RUT
« Respuesta #2 : abril 16, 2016, 02:41:21 pm »
Cabros, les dejó un apquete en PHP para trabajr con el RUT:
http://freshworkstudio.github.io/ChileanBundle/

Para generar ruts sería algo como esto:

for($i = 0; $i < 10; $i++)
{
    $rut = new \Freshwork\ChileanBundle\Rut(rand(1000000, 25000000));
    echo $rut->fix()->format() . " <br />\n";
}


Esto general 10 ruts aleatoreos entre 1.000.000 y 25.000.000

Gonzalo

  • Visitante
Re:Buén validador de RUT en PHP
« Respuesta #3 : abril 16, 2016, 02:56:36 pm »
Incluso podría ser más simple:

for($i = 0; $i < 10; $i++)
    echo \Freshwork\ChileanBundle\Rut::set(rand(1000000, 25000000))->fix()->format() . "\n";

http://freshworkstudio.github.io/ChileanBundle/

Desconectado WHK

  • 吴阿卡
  • Administrador
  • Aportador
  • *****
  • Mensajes: 555
  • Karma: +15/-3
  • Coder
    • Yahoo Instant Messenger - yan_uniko_102
    • Ver Perfil
    • WHK
    • Email
Re:Buén validador de RUT en PHP
« Respuesta #4 : mayo 20, 2016, 09:18:41 pm »
Acá hay una pagina con ejemplos de la implementación del rut en muchos lenguajes de programación pasando por .net, java, etc.

https://es.wikipedia.org/wiki/Anexo:Implementaciones_para_algoritmo_de_rut

C#
Código: cs [Seleccionar]
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 ==
            {
             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++

Código: cpp [Seleccionar]
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';
}


Java

Código: java [Seleccionar]
    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);
    }


Javascript

Código: javascript [Seleccionar]
  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:')));


MATLAB

Código: [Seleccionar]
r=input('Ingrese rut:');

a=floor(r/10^7);
b=floor(r/10^6)-(10*a);
c=floor(r/10^5)-(100*a+10*b);
d=floor(r/10^4)-(10^3*a+100*b+10*c);
e=floor(r/10^3)-(10^4*a+10^3*b+100*c+10*d);
f=floor(r/10^2)-(10^5*a+10^4*b+10^3*c+100*d+10*e);
g=floor(r/10^1)-(10^6*a+10^5*b+10^4*c+10^3*d+100*e+10*f);
h=r-(10^7*a+10^6*b+10^5*c+10^4*d+10^3*e+100*f+10*g);

sum=h*2+g*3+f*4+e*5+d*6+c*7+b*2+a*3;
resto=sum-floor(sum/11)*11;

verif=11-resto;

disp('El numero verificador es:')
if (verif<10)
    disp(verif)
end
if (verif==11)
    disp('0')
end
if (verif==10)
    disp('K')
end

Objective-C

Código: [Seleccionar]
//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 6

Código: [Seleccionar]
    #!/usr/bin/perl6
    my ($RUT, @RUT, $digito);

    $RUT = @*ARGS;                          # leemos el argumento pasado al programa
    @RUT = $RUT.split('').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

PHP

Código: php [Seleccionar]
  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

Código: sql [Seleccionar]
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;


PSeInt

Código: [Seleccionar]
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

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


Ruby

Código: ruby [Seleccionar]
def digito_verificador(rut)
  dv = (11-(rut.split('').map(&:to_i).reverse.each_with_index.map { |e, i| e*(2+i%6) }).inject(:+))%11
  if dv < 10 then dv.to_s else 'k' end
end


Transact-SQL

Código: sql [Seleccionar]
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 Excel

Código: [Seleccionar]
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
Mi WEB - The Hacktivism is not a crime - Si no lo hago yo, que lo hagan otros -


. . . . . . . .