COLABORACIÓN > Utilerias y Programas

Como calcular el CURP (México), RNC (Rep. Dom.), DNI y NIF (España)

<< < (5/5)

edyaca:
 :smiley:  muchas gracias

Sergio:
Me sumo a los algoritmos de validacion de codigos con este que valida un número de cuenta de banco español.

Son siempre de 20 digitos, 4+4+2+10 = banco+sucursal+digitos de control+numero de cuenta, y los digitos de control se permite dejarlos a ** si no se conocen.


--- Código: ---procedure cccValidaEspana(pCta: String);
var
  banco, control, cuenta: String;
  i: integer;
  cero: boolean;
begin
  // Para evitar errores al insertar registros
  if pCta<>'' then begin
    if length(pCta)<>20 then
      raise Exception.Create('El texto a validar como numero de cuenta no tiene 20 caracteres');
    cero:= true;
    for i:= 1 to 8 do
      cero:= cero and (pCta[i]='0');
    if cero then
      raise EHCException.Create('No se admiten cuenta bancarias con el codigo de banco y/o sucursal a cero, si no conoce la cuenta dejelo en blanco.');

    Banco:=   copy(pCta, 1, 8);
    Control:= copy(pCta, 9, 2);
    Cuenta:=  copy(pCta,11,10);

    try
      StrToFloat(Banco+Cuenta)
    except
      raise Exception.Create('Cuenta bancaria erronea'+#10+
               'Solo debe contener numeros ó asteriscos en los digitos de control');
    end;
    if (Control[1] in ['0'..'9']) and (Control[2] in ['0'..'9']) then begin
      if Control <> cccSuma(Banco)+cccSuma(Cuenta) then
        raise Exception.Create('Cuenta bancaria erronea'+#10+
              'Los digitos de control no se corresponden con la cuenta');
    end else if Control <> '**' then
      raise Exception.Create('Los digitos de control deben ser solo digitos ó asteriscos')
  end;
end;

function  cccSuma( Str: String ): String;
var i, lon, n: integer;
    Pesos: array [0..9] of integer;
begin
  Pesos[0]:= 6; Pesos[1]:= 3; Pesos[2]:= 7; Pesos[3]:= 9; Pesos[4]:=10;
  Pesos[5]:= 5; Pesos[6]:= 8; Pesos[7]:= 4; Pesos[8]:= 2; Pesos[9]:= 1;
  lon:= length(Str);
  n:= 0;
  for i:= 1 to lon do
    n:= n+ StrToInt(copy(Str,lon-i+1,1)) * Pesos[i-1];
  n:= 11 - ( n mod 11 );
  if n=10 then n:=1;
  if n=11 then n:=0;
  Result:= IntToStr(n);
end;

--- Fin del código ---

Sergio:
Y un pseudo-codigo para cálcular el código IBAN de una cuenta de banco cualquiera:


--- Código: ---1) Tomas el numero de cuenta sin espacios ni guiones ni nada (ejemplo aleman, sin digitos de control) :
   370400440532013000
2) Añades al final el pais y digitos de control vacios 00 ('ES00' ó 'DE00' en el ejemplo):
   370400440532013000DE00
3) Cambias las letras que queden a numeros segun esta tabla:
   A=10, B=11, C=12, D=13, E=14, F=15, G=16, H=17, I=18, J=19, K=20, L=21, M=22,
   N=23, O=24, P=25, Q=26, R=27, S=28, T=29, U=30, V=31, W=32, X=33, Y=34, Z=35
   370400440532013000DE00 se convierte en 370400440532013000131400
4) 370400440532013000131400 mod 97 = 9
5) 98 - 9 = 89
   Al final quedaria asi: DE89 37040044 0532013000

--- Fin del código ---

Fuente: http://www.europebanks.info/ibanguide.htm#5


Calculadora (para cuentas en España en principio): http://www.bankia.es/es/comercio-exterior/utilidades/codigo-iban

Ejemplos de cuentas bancarias con su IBAN añadido y otros detalles de todos los paises europeos: http://www.ecbs.org/iban.htm

La lista más completa que he encontrado de paises con sus formatos de cuenta: http://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN

Nota: Aunque el algorítmo para calcular estos 2 dígitos es siempre el mismo, hay "detalles" importantes que saber según el país: En algunos paises se usa unos dígitos de control fijos para todas las cuentas (porque su código de cuenta ya incluye estos mismos códigos de control, con lo que "repetir" el algorítmo te dá siempre un 1) y, también, es necesario conocer el largo total de la cuenta con su IBAN para poder comprobarlo antes de nada, y esta longitud depende del país.

Sería interesante que si alguien tiene el código IBAN de un par de cuentas, pase el algoritmo y así podríamos saber en qué paises se usa y en cuales no, si es que existe alguno que no lo sé a ciencia cierta.

seoane:
Ampliando lo comentado por Sergio, dejo algo de código:

--- Código: ---unit IBAN;

interface

uses
  SysUtils;

function CalcularIBANEsp(Entidad, Oficina, DC, Cuenta: String): String; overload;
function CalcularIBANEsp(CCC: String): String; overload;
function ComprobarIBAN(Str: String): Boolean;

implementation

function EsNumero(Str: String): Boolean;
var
  i: Integer;
begin
  Result:= TRUE;
  for i:= 1 to Length(Str) do
    if not (Str[i] in ['0'..'9']) then
    begin
      Result:= FALSE;
      break;
    end;
end;

function mod97(Str: String): Integer;
begin
  Result:= 0;
  while Length(Str) > 0 do
  begin
    Result:= StrToInt(IntToStr(Result) + Copy(Str,1,6)) mod 97;
    Delete(Str,1,6);
  end;
end;

function lPad(Str: String; n: Integer): String;
begin
  while Length(Str) < n do
    Str:= '0' + Str;
  Result:= Str;
end;

// Calcula el IBAN para una cuenta española
function CalcularIBANEsp(Entidad, Oficina, DC, Cuenta: String): String; overload;
begin
  if EsNumero(Entidad + Oficina + DC + Cuenta) then
  begin
    Entidad:= lPad(Entidad,4);
    Oficina:= lPad(Oficina,4);
    DC:=      lPad(Dc,2);
    Cuenta:=  lPad(Cuenta,10);
    Result:= Format('IBAN ES%2.2d %s %s %s%s %s %s', [
      98 - mod97(Entidad + Oficina + DC + Cuenta + '142800'),
      Entidad,Oficina,DC,Copy(Cuenta,1,2),Copy(Cuenta,3,4), Copy(Cuenta,7,4)]);
  end else
    Result:= EmptyStr;
end;

// Calcula el IBAN para una cuenta española
function CalcularIBANEsp(CCC: String): String; overload;
begin
  Result:= EmptyStr;
  if (Length(CCC)=20) and EsNumero(CCC)  then
    Result:= CalcularIBANEsp(Copy(CCC,1,4),Copy(CCC,5,4),Copy(CCC,9,2),
      Copy(CCC,11,10));
end;

// Comprueba cualquier IBAN
function ComprobarIBAN(Str: String): Boolean;
var
  i: Integer;
  S: String;
begin
  Result:= FALSE;
  if Uppercase(Copy(Str,1,Length('IBAN '))) = 'IBAN ' then
    Str:= Copy(Str,5,MAXINT);
  S:= EmptyStr;
  for i:= 1 to Length(Str) do
    if Str[i] in ['0'..'9'] then
      S:= S + Str[i]
    else if Upcase(Str[i]) in ['A'..'Z'] then
      S:= S + IntToStr(Ord(Str[i])-Ord('A')+10)
    else if Str[i] <> #32 then
      Exit;
  S:= Copy(S,7,MAXINT) + Copy(S,1,6);
  Result:= mod97(S) = 1;
end;

end.


--- Fin del código ---

Son dos funciones, una sirve para calcular el IBAN de una cuenta española y la otra para comprobar cualquier IBAN (aunque sean de otro país).

Por ejemplo:

--- Código: ---  Writeln(CalcularIBANEsp('20800708913000012345'));
  Writeln(ComprobarIBAN(CalcularIBANEsp('20800708913000012345')));     // El número de cuenta del ejemplo no es de verdad !!!

--- Fin del código ---

Navegación

[0] Índice de Mensajes

[*] Página Anterior

Ir a la versión completa