Alaska Software Inc. - Algoritmos de uso diario
Username: Password:
AuthorTopic: Algoritmos de uso diario
Jose Luis OterminAlgoritmos de uso diario
on Thu, 13 Jan 2011 18:42:55 -0300
Estimados Colegas,

En nuestros sistemas usamos siempre los algoritmos de validacin de cosas 
tan cotidianas como:

Clave Fiscal, Clave Bancaria Unica, etc, todos ellos relacionados con 
clientes y proveedores.

Podramos publicar nuestros algoritmos de validacin de las claves fiscales, 
tarjetas de crdito, claves bancarias, etc.

En Argentina las siguientes palabras definen a las claves:

CUIT - Clave Unica de Identificacin Tributaria: Picture: 99-99.999.999-9
IIBB - Impuesto sobre los Ingresos Brutos. Su formato vara segn la Zona 
Fiscal.
CBU - Clave Bancaria nica. Formato: 20 dgitos.

En un mensaje separado publicar los algoritmos que uso.
Invito a los presentes a compartir los suyos 

Gracias

Saludos

Jos Luis Otermin
Alaska Software
Jose Luis OterminRe: Algoritmos de uso diario
on Thu, 13 Jan 2011 18:47:40 -0300
Validacin de CUIT (Argentina).

////////////////////////////////////////////////////

 calculo del digito verificador del CUIT/CUIL

FUNCTION CUIT( xCUIT )

////////////////////////////////////////////////////

  LOCAL cCUIT   := Var2Char(xCUIT)
  LOCAL aFactor := Array(10)
  LOCAL i, nSUMA
  aFactor[1]  := 5
  aFactor[2]  := 4
  aFactor[3]  := 3
  aFactor[4]  := 2
  aFactor[5]  := 7
  aFactor[6]  := 6
  aFactor[7]  := 5
  aFactor[8]  := 4
  aFactor[9]  := 3
  aFactor[10] := 2
  nSuma       := 0
  I           := 1

  FOR i :=  1 TO 10
     nSUMA += VAL(SUBSTR(cCUIT,I,1)) * aFactor[i]
  NEXT

   'vsuma            ',vsuma
  //? 'vsuma % 11       ',mod(vsuma, 11)
  //? '11 - (vsuma % 11)',11 - mod(vsuma , 11)
  lOK  := (val(substr(cCUIT,11,1))<>(11-mod(nSuma,11)))
  IF  .NOT. lOk
     MSGBox( "CUIT Incorrecto", "Atencion")
  ENDIF
RETURN lOK
Jose Luis OterminRe: Algoritmos de uso diario - CBU
on Thu, 13 Jan 2011 18:57:51 -0300
El caso del CBU es algo ms complejo: (no son 20 dgitos sino 22).

La rutina de validacion del CBU (Argentina) segn el Banco Central de la 
Repblica Argentina (BCRA) es:

CBU1 (8 digitos) y CBU2 (14 dgitos)
----------------------------------------------
 Los mismos debern responder a la estructura establecida por BCRA:
 La estructura del CBU1 de BCRA es:
 Posicin 1 a 3: Cdigo del Banco
 Posicin 4 a 7: Cdigo de la Sucursal
 Posicin 8     : Dgito verificador del CBU1
 ej.: 26500135

 La estructura del CBU2 de BCRA es:
 Posicin 1 a 13: Nro. de la Cuenta del Cliente
 Posicin 14      : Dgito verificador del CBU2
 ej.: 02001343624137

 La forma de clculo es la siguiente:

CBU2      0     2   0   0    1     7   1   3      4     2     9   3    2   4
          *    3     9   7   1    3     9   7   1      3     9     7   1
3   1
Resultado 0 +18+ 0+ 0+ 3+ 63+ 7+ 3+ 12+ 18+ 63+ 3 +6+ 4 =200

Se multiplica cada dgito del CBU1 o CBU2 (excepto el digito verificador -
pos.8/14- que se multiplica por 1) por  3, 9, 7, y 1, sucesivamente, se
suman los productos (en el ej.: =200) y se verifica que el ltimo dgito de
la suma es cero, de lo contrario el CBU es errneo.

Por lo tanto, el algoritmo queda:

FUNCTION CBU( cCBU )
 Clave Bancaria Uniforme
 
http://infoleg.mecon.gov.ar/infolegInternet/anexos/45000-49999/47564/norma.htm
 COMUNICACION "A" 2622 (14/11/97).
 Ref.: Circular CAMCO 1-98. RUNOR 1-250. Sistema Nacional de Pagos.
 Clave Bancaria Uniforme (CBU).
 B.O: 28/11/97

      LOCAL aFactor1       := {7,1,3,9,7,1,3}  9713^
      LOCAL aFactor2       := {3,9,7,1,3,9,7,1,3,9,7,1,3}

      LOCAL cBankBranch    := SUBSTR( cCBU, 1,  7)
      LOCAL cBankDV        := SUBSTR( cCBU, 8,  1)
      LOCAL cAccount       := SUBSTR( cCBU, 9, 13)
      LOCAL cAccountDV     := SUBSTR( cCBU,22,  1)

      lBankDVok    := (VAL(cBankDV)==CalcDV( cBankBranch, aFactor1))
      lAccountDVok := (VAL(cAccountDV)==CalcDV( cAccount, aFactor2))

      ? "cBankDV = CalcDV( cBankBranch, aPonderador)"
      ? cBankDV
      ?? " = "
      ?? CalcDV( cBankBranch, aFactor1)
      ? "----"
      ? "cAccountDV = CalcDV( cAccount, aPonderador)"
      ? cAccountDV
      ?? " = "
      ?? CalcDV( cAccount, aFactor2)


RETURN ( lBankDVok .AND. lAccountDVok)

FUNCTION CalcDV( cString, aFactor )
      LOCAL i                subndice para recorrer la cadena
      LOCAL j                subndice del ponderador (mdulo 4)
      LOCAL nSuma            sumatoria de los productos parciales
      LOCAL nDigito          dgito verificador
      LOCAL nLen  := LEN( cString )

      nSuma := 0
      j     := 0
      ? "CalcDV"
      ? "--------------"
      FOR i := 1 TO nLen
         ? "VAL(SUBSTR(cString, "+str(i)+" , 1))  * aFactor["+str(i)+" ] "
         ? VAL(SUBSTR(cString, i, 1))
         ?? " * "
         ?? aFactor[i]
         nSuma += VAL(SUBSTR(cString, i, 1)) * aFactor[nLen-i+1]
      NEXT
      ? "--------------"
      nDV   := (10 -( nSuma % 10)) % 10
      ? "nDV = "
      ?? nDV
RETURN nDV
Hector PezoaRe: Algoritmos de uso diario - CBU
on Thu, 20 Jan 2011 12:54:04 -0300
Estimado Jose pepe

Yo hago ritmo en la maana y en la tarde tambien, ya que estoy obligado a 
llevarlo siempre , no es como el cuico suyo,
 este es mas simple y se llama rut,  y no piense mal, su nombre es Rol Unico 
Tributario, y se valida de la siguiente forma :

Function _Rut(rut_i)
Local rut_p, rut_m , rut_s, rut_d

   rut_p = 8
   rut_m = 2
   rut_s = 0
   do while substr(rut_i,9,1) = " "
      rut_i = "0" + substr(rut_i,1,8)
   enddo
   do while rut_p >= 1
      if substr(rut_i,rut_p,1) < "0" .or. substr(rut_i,rut_p,1) > "9"
         rut_i = "         "
         return .f.
      else
         rut_s = rut_s + val(substr(rut_i,rut_p,1)) * rut_m
         rut_m = rut_m + 1
         rut_p = rut_p - 1
         if rut_m = 8
            rut_m = 2
         endif
      endif
   enddo
   if rut_i != "         "
      rut_s = rut_s - 11 * int(rut_s / 11)
      if rut_s = 0
         rut_d = "0"
      elseif rut_s = 1
         rut_d = "K"
      else
         rut_d = str(11 - rut_s,1)
      endif
      if substr(rut_i,9,1) != rut_d
         rut_i = "         "
         return .f.
      endif
   endif
   return .t.

Salute
Hector






<Jose Luis Otermin> escribi en el mensaje 
news:283aafbf$6bdd03fe$447be@news.alaska-software.com...
> El caso del CBU es algo ms complejo: (no son 20 dgitos sino 22).
>
> La rutina de validacion del CBU (Argentina) segn el Banco Central de la 
> Repblica Argentina (BCRA) es:
>
> CBU1 (8 digitos) y CBU2 (14 dgitos)
> ----------------------------------------------
> Los mismos debern responder a la estructura establecida por BCRA:
> La estructura del CBU1 de BCRA es:
> Posicin 1 a 3: Cdigo del Banco
> Posicin 4 a 7: Cdigo de la Sucursal
> Posicin 8     : Dgito verificador del CBU1
> ej.: 26500135
>
> La estructura del CBU2 de BCRA es:
> Posicin 1 a 13: Nro. de la Cuenta del Cliente
> Posicin 14      : Dgito verificador del CBU2
> ej.: 02001343624137
>
> La forma de clculo es la siguiente:
>
> CBU2      0     2   0   0    1     7   1   3      4     2     9   3    2 
> 4
>          *    3     9   7   1    3     9   7   1      3     9     7   1
> 3   1
> Resultado 0 +18+ 0+ 0+ 3+ 63+ 7+ 3+ 12+ 18+ 63+ 3 +6+ 4 =200
>
> Se multiplica cada dgito del CBU1 o CBU2 (excepto el digito verificador -
> pos.8/14- que se multiplica por 1) por  3, 9, 7, y 1, sucesivamente, se
> suman los productos (en el ej.: =200) y se verifica que el ltimo dgito 
> de
> la suma es cero, de lo contrario el CBU es errneo.
>
> Por lo tanto, el algoritmo queda:
>
> FUNCTION CBU( cCBU )
>  Clave Bancaria Uniforme
>  
> http://infoleg.mecon.gov.ar/infolegInternet/anexos/45000-49999/47564/norma.htm
>  COMUNICACION "A" 2622 (14/11/97).
>  Ref.: Circular CAMCO 1-98. RUNOR 1-250. Sistema Nacional de Pagos.
>  Clave Bancaria Uniforme (CBU).
>  B.O: 28/11/97
> 
>      LOCAL aFactor1       := {7,1,3,9,7,1,3}  9713^
>      LOCAL aFactor2       := {3,9,7,1,3,9,7,1,3,9,7,1,3}
>
>      LOCAL cBankBranch    := SUBSTR( cCBU, 1,  7)
>      LOCAL cBankDV        := SUBSTR( cCBU, 8,  1)
>      LOCAL cAccount       := SUBSTR( cCBU, 9, 13)
>      LOCAL cAccountDV     := SUBSTR( cCBU,22,  1)
>
>      lBankDVok    := (VAL(cBankDV)==CalcDV( cBankBranch, aFactor1))
>      lAccountDVok := (VAL(cAccountDV)==CalcDV( cAccount, aFactor2))
>
>      ? "cBankDV = CalcDV( cBankBranch, aPonderador)"
>      ? cBankDV
>      ?? " = "
>      ?? CalcDV( cBankBranch, aFactor1)
>      ? "----"
>      ? "cAccountDV = CalcDV( cAccount, aPonderador)"
>      ? cAccountDV
>      ?? " = "
>      ?? CalcDV( cAccount, aFactor2)
>
>
> RETURN ( lBankDVok .AND. lAccountDVok)
>
> FUNCTION CalcDV( cString, aFactor )
>      LOCAL i                subndice para recorrer la cadena
>      LOCAL j                subndice del ponderador (mdulo 4)
>      LOCAL nSuma            sumatoria de los productos parciales
>      LOCAL nDigito          dgito verificador
>      LOCAL nLen  := LEN( cString )
>
>      nSuma := 0
>      j     := 0
>      ? "CalcDV"
>      ? "--------------"
>      FOR i := 1 TO nLen
>         ? "VAL(SUBSTR(cString, "+str(i)+" , 1))  * aFactor["+str(i)+" ] "
>         ? VAL(SUBSTR(cString, i, 1))
>         ?? " * "
>         ?? aFactor[i]
>         nSuma += VAL(SUBSTR(cString, i, 1)) * aFactor[nLen-i+1]
>      NEXT
>      ? "--------------"
>      nDV   := (10 -( nSuma % 10)) % 10
>      ? "nDV = "
>      ?? nDV
> RETURN nDV
>