Ver Mensaje Individual
  #6  
Antiguo 23-05-2007
Avatar de Goyo
Goyo Goyo is offline
Miembro
 
Registrado: feb 2006
Posts: 89
Reputación: 19
Goyo Va por buen camino
Question Encontre el codigo que lo obtiene con la homoclave.

la idea es implementarlo en delphi, no se como pasarlo aqui les muestro un link donde se encuentra (pero esta en C# y Visual Fox PRO), la idea (y creo que de muchos) es tenerlo en delphi....

http://www.forosdelweb.com/showthread.php?t=317714

por si no lo pueden abrir a qui les pongo el codigo:
Cita:
CODIGO DESARROLLADO EN VISUAL FOX PRO PARA GENERAR RFC CON HOMOCLAVE Y DIGITO VERIFICADOR SEGUN HACIENDA EN MEXICO


FUNCTION GENERA_RFC(CL_PAT,CL_MAT,CL_NOM,DL_FECNAC)
DIMENSION arre8(10),arre6(4),arre2(10),arre9(1),anex11(1),anex12(1),anex31(1),anex32(1)
arre8[1]="DE "
arre8[2]="DEL "
arre8[3]="LA "
arre8[4]="LOS "
arre8[5]="LAS "
arre8[6]="Y "
arre8[7]="MC "
arre8[8]="MAC "
arre8[9]="VON "
arre8[10]="VAN "

arre6[1]="JOSE "
arre6[2]="MARIA "
arre6[3]="J "
arre6[4]="MA "

arre2[1]="A"
arre2[2]="E"
arre2[3]="I"
arre2[4]="O"
arre2[5]="U"
arre2[6]="a"
arre2[7]="e"
arre2[8]="i"
arre2[9]="o"
arre2[10]="u"
arre9[1]=""
sino = "S"
malas ="BUEIBUEYCACACACOCAGACAGOCAKACAKOCOGECOJAKOGEKOJOKAKAKULOMAMEMAMO"
malas = malas +"MEARMEASMEONMIONCOJECOJICOJOCULOFETOGUEYJOTOKACAKACOKAGA"
malas = malas + "KAGOMOCOMULAPEDAPEDOPENEPUTAPUTOQULORATARUIN"
for x = 1 to Len(malas) step 4
DIMENSION arre9(X)
arre9(X)=SubStr(malas, x, 4)
next
anex11[1] = ''
anex12[1] = ''
taba11 = "*0123456789&\ABCDEFGHIJKLMNOPQRSTUVWXYZ"
taba12 = "000001020304050607080910101112131415161718192122232425262728293233343536373839"
for x = 1 to Len(taba11)
DIMENSION anex11(x),anex12(x)
anex11(x)=SubStr(taba11, x, 1)
two = x * 2 - 1
anex12(x)=SubStr(taba12, two, 2)
next
malas = ""
taba11 = ""
taba12 = ""
taba21 = "00010203040506070809101112131415161718192021222324252627282930313233"
taba22 = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"
for x = 1 to Len(taba21) step 2
DIMENSION anex21(x),anex22(x)
anex21(x)=SubStr(taba21, x, 2)
two = ( x + 1 ) / 2
anex22(x)=SubStr(taba22, two, 1)
next
taba21 = ""
taba22 = ""
taba11 = "0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ*"
taba12 = "0001020304050607080910111213141516171819202122232425262728293031323334353637"
anex31(1) = ''
anex32(1) = ''
FOR x = 1 to Len(taba11)
DIMENSION anex31(x),anex32(x)
anex31(x)=SubStr(taba11, x, 1)
two = (x * 2) - 1
anex32(x)=SubStr(taba12, two, 2)
NEXT
STORE SPACE(0) TO taba11,taba12,wrfc,wnumer6,wlos3
STORE Space(30) TO wpaterno,wmaterno,wnombre,paterno,materno,nombre
mask = Replicate("!", 30)
wanual = VAL(STR(YEAR(dl_fecnac),4)+PADL(ALLTRIM(STR(MONTH(dl_Fecnac),2)),2,'0')+PADL(ALLTRIM(STR(DAY(dl_fecn ac),2)),2,'0'))
wpaterno = CL_PAT
wmaterno = CL_MAT
wnombre = CL_NOM
IF nacio(wanual) = .F.
=MESSAGEBOX('La Fecha de Nacimiento es Incorrecta',16+0,'Error')
RETURN SPACE(0)
ENDIF
IF los3(wpaterno, wmaterno, wnombre) = .F.
=MESSAGEBOX('El Nombre del Empleado es Incorrecto',16+0,'Error')
RETURN SPACE(0)
ENDIF
finice = .F.
octava()
sexta()
tercera()
wbase = alltrim(alltrim(paterno) + " " + alltrim(materno) +" " + alltrim(nombre))
IF ( Len(paterno) = 0 .OR. Len(materno) = 0 )
septima()
finice = .T.
ENDIF
IF ( !finice )
IF ( Len(paterno) < 3 )
cuarta()
finice = .T.
ENDIF
ENDIF
IF ( !finice )
prime_segu()
ENDIF
RETURN wrfc
ENDFUNC

PROCEDURE SHOW_IT( Arg1 )
cuatro = SubStr(Arg1, 1, 4)
van = ascan(arre9, cuatro)
if ( van > 0 )
wrfc = stuff(wrfc, 4, 1, "X")
endif
homoni()
digito()
RETURN
ENDPROC
PROCEDURE PRIME_SEGU()
letra = SubStr(paterno, 2, 1)
for x = 2 to Len(paterno)
van = ascan(arre2, SubStr(paterno, x, 1))
if ( van > 0 )
letra = arre2[ van ]
x = Len(paterno) + 8
endif
next
wrfc = SubStr(paterno, 1, 1) + letra + SubStr(materno, 1, 1) + SubStr(nombre, 1, 1)
wrfc = wrfc + wnumer6 + "000"
show_it(wrfc)
RETURN
ENDPROC

PROCEDURE TERCERA()
IF ( SubStr(nombre, 1, 2) = "CH" )
nombre = stuff(nombre, 1, 2, "C")
ELSE
IF ( SubStr(nombre, 1, 2) = "LL" )
nombre = stuff(nombre, 1, 2, "L")
ENDIF
ENDIF
IF ( SubStr(paterno, 1, 2) = "CH" )
paterno = stuff(paterno, 1, 2, "C")
ELSE
IF ( SubStr(paterno, 1, 2) = "LL" )
paterno = stuff(paterno, 1, 2, "L")
ENDIF
ENDIF
IF ( SubStr(materno, 1, 2) = "CH" )
materno = stuff(materno, 1, 2, "C")
ELSE
IF ( SubStr(materno, 1, 2) = "LL" )
materno = stuff(materno, 1, 2, "L")
ENDIF
ENDIF
RETURN
ENDPROC

********************************
PROCEDURE CUARTA()
wrfc = SubStr(paterno, 1, 1) + SubStr(materno, 1, 1) +SubStr(nombre, 1, 2) + wnumer6 + "000"
show_it(wrfc)
RETURN
ENDPROC

********************************
PROCEDURE SEXTA()
posi = At(" ", nombre)
IF ( posi > 0 )
FOR xx = 1 to ALen(arre6,1)
nombre = strtran(nombre, arre6[xx])
NEXT
ENDIF
RETURN
ENDPROC

********************************
PROCEDURE SEPTIMA()
IF ( Len(paterno) = 0 .AND. Len(materno) > 0 )
unosolo = materno
ELSE
IF ( Len(paterno) > 0 .AND. Len(materno) = 0 )
unosolo = paterno
ENDIF
ELSE
unosolo = nombre
endif
wrfc = SubStr(unosolo, 1, 2) + SubStr(nombre, 1, 2) + wnumer6 + "000"
show_it(wrfc)
RETURN
ENDPROC

********************************
PROCEDURE OCTAVA()
FOR xx = 1 to aLen(arre8,1)
paterno = strtran(paterno, arre8[ xx ])
materno = strtran(materno, arre8[ xx ])
nombre = strtran(nombre, arre8[ xx ])
NEXT
RETURN
ENDPROC

Function NACIO( Arg1 )
LOCAL ll_error
DIMENSION Local1(12)
Local1(1)=31
Local1(2)=28
Local1(3)=31
Local1(4)=30
Local1(5)=31
Local1(6)=30
Local1(7)=31
Local1(8)=31
Local1(9)=30
Local1(10)=31
Local1(11)=30
Local1(12)=31
if ( Arg1 = 0 )
bb = .F.
else
todo = Str(Arg1, 8)
bb = .T.
uno = Val(SubStr(todo, 7, 2))
dos = Val(SubStr(todo, 5, 2))
tres = Val(SubStr(todo, 1, 4))
if ( Arg1 = 0 .OR. uno = 0 .OR. dos = 0 )
bb = .F.
ELSE
IF ( dos <= 0 .OR. dos > 12 )
bb = .F.
ELSE
bisies = Local1[ dos ]
sanual = Str(tres, 4)
sanual2 = Val(sanual)
if ( dos = 2 .AND. Int(sanual2 / 4) * 4 = sanual2 )
bisies = bisies + 1
endif
ENDIF
if ( bb )
if ( uno <= 0 .OR. uno > bisies )
bb = .F.
endif
endif
endif
if ( !bb )
=MESSAGEBOX('ERROR EN FECHA DE NACIMIENTO',16+0,'Error')
else
wnumer6 = SUBSTR(Str(tres, 4),3,2)
if ( dos < 10 )
wnumer6 = wnumer6 + "0" + Str(dos, 1)
else
wnumer6 = wnumer6 + Str(dos, 2)
endif
if ( uno < 10 )
wnumer6 = wnumer6 + "0" + Str(uno, 1)
else
wnumer6 = wnumer6 + Str(uno, 2)
endif
ENDIF
Return bb
ENDFUNC

Function LOS3( Arg1, Arg2, Arg3 )
paterno = Trim(Arg1)
materno = Trim(Arg2)
nombre = Trim(Arg3)
wlos3 = alltrim(alltrim(Arg1) + " " + alltrim(Arg2) + " " + ;
alltrim(Arg3))
wlos3 = strtran(wlos3, " ", " ")
IF ( Len(wlos3) <= 6 )
Return .F.
ENDIF
Return .T.
ENDFUNC


PROCEDURE HOMONI()
valores = "0"
wbase = alltrim(alltrim(wpaterno) + " " + alltrim(wmaterno) +" " + alltrim(wnombre))
FOR x = 1 TO Len(wbase)
unok = SubStr(wbase, x, 1)
IF ( unok = " " )
unok = "*"
ENDIF
van = ascan(anex11, unok)
IF ( van > 0 )
valores = valores + anex12[ van ]
ELSE
valores = valores + "00"
ENDIF
NEXT
sumas = 0
FOR x = 1 TO Len(valores) - 1
prod1 = Val(SubStr(valores, x, 2))
prod2 = Val(SubStr(valores, x + 1, 1))
prod3 = prod1 * prod2
sumas = sumas + prod3
NEXT
zumass = Str(sumas, 10, 0)
zumass = right(zumass, 3)
zumas = Val(zumass)
solotres = zumas
cociente = Int(solotres / 34)
residuo = solotres - cociente * 34
IF ( cociente < 10 )
wrok = "0" + Str(cociente, 1)
ELSE
wrok = Str(cociente, 2)
ENDIF
van = ascan(anex21, wrok)
IF ( van > 0 )
homo = anex22[ van ]
ELSE
homo = "1"
ENDIF
IF ( residuo < 10 )
wrok = "0" + Str(residuo, 1)
ELSE
wrok = Str(residuo, 2)
ENDIF
van = ascan(anex21, wrok)
IF ( van > 0 )
homo = homo + anex22[ van ]
ELSE
homo = homo + "1"
ENDIF
wrfc = SubStr(wrfc, 1, 10) + homo
RETURN
ENDPROC

PROCEDURE DIGITO()
valores = ""
FOR x = 1 TO Len(wrfc)
unok = SubStr(wrfc, x, 1)
IF unok = " "
unok = "*"
ENDIF
van = ascan(anex31, unok)
IF van > 0
valores = valores + anex32[ van ]
ELSE
valores = valores + "00"
ENDIF
NEXT
sumas = 0
trece = 13
FOR x = 1 TO 12
prod1 = Val(SubStr(valores, x * 2 - 1, 2))
prod3 = prod1 * trece
sumas = sumas + prod3
trece = trece - 1
NEXT
cociente = Int(sumas / 11)
residuo = Int(sumas) - cociente * 11
IF residuo = 0
dijito = "0"
ELSE
valor = 11 - residuo
IF ( valor = 10 )
dijito = "A"
ELSE
entrer = Str(valor, 10, 0)
dijito = right(entrer, 1)
ENDIF
ENDIF
wrfc = wrfc + dijito
RETURN
ENDPROC
y aqui esta en C#

Cita:
/// <summary>
/// Contiene Funciones para el calculo de RFC y CURP
/// </summary>
public class CURPRFC
{
/// <summary>
/// Calcula el RFC de una persona física su homoclave incluida.
/// </summary>
/// <param name="nombre">Nombre(s) de la persona</param>
/// <param name="apellidoPaterno">Apellido paterno de la persona</param>
/// <param name="apellidoMaterno">Apellido materno de la persona</param>
/// <param name="fecha">Fecha en formato dd/MM/yy (12/10/68)</param>
/// <returns>Regresa el RFC como cadena de caracteres</returns>
static public string CalcularRFC(string nombre, string apellidoPaterno, string apellidoMaterno, string fecha)
{
//Cambiamos todo a mayúsculas
nombre = nombre.ToUpper();
apellidoPaterno = apellidoPaterno.ToUpper();
apellidoMaterno = apellidoMaterno.ToUpper();

//RFC que se regresará
string rfc = String.Empty;

//Quitamos los espacios al principio y final del nombre y apellidos
nombre.Trim();
apellidoPaterno = apellidoPaterno.Trim();
apellidoMaterno = apellidoMaterno.Trim();

//Quitamos los artículos de los apellidos
apellidoPaterno = QuitarArticulos(apellidoPaterno);
apellidoMaterno = QuitarArticulos(apellidoMaterno);

//Agregamos el primer caracter del apellido paterno
rfc = apellidoPaterno.Substring(0, 1);

//Buscamos y agregamos al rfc la primera vocal del primer apellido
foreach (char c in apellidoPaterno)
{
if (EsVocal(c))
{
rfc += c;
break;
}
}

//Agregamos el primer caracter del apellido materno
rfc += apellidoMaterno.Substring(0, 1);

//Agregamos el primer caracter del primer nombre
rfc += nombre.Substring(0, 1);

//agregamos la fecha yymmdd (por ejemplo: 680825, 25 de agosto de 1968 )
rfc += fecha.Substring(6, 2) +
fecha.Substring(3, 2) +
fecha.Substring(0, 2);

//Le agregamos la homoclave al rfc
CalcularHomoclave(apellidoPaterno + " " + apellidoMaterno + " " + nombre, fecha, ref rfc);

return rfc;
}

/// <summary>
/// Calcula la homoclave
/// </summary>
/// <param name="nombreCompleto">El nombre completo de la persona en el formato "ApellidoPaterno ApellidoMaterno Nombre(s)"</param>
/// <param name="fecha">fecha en el formato "dd/MM/yy"</param>
/// <param name="rfc">rfc sin homoclave, esta se pasa con ref y después de la función tendrá la homoclave</param>
static private void CalcularHomoclave(string nombreCompleto, string fecha, ref string rfc)
{
//Guardara el nombre en su correspondiente numérico
StringBuilder nombreEnNumero = new StringBuilder(); ;
//La suma de la secuencia de números de nombreEnNumero
long valorSuma = 0;

#region Tablas para calcular la homoclave
//Estas tablas realmente no se porque son como son
//solo las copie de lo que encontré en internet

#region TablaRFC 1
Hashtable tablaRFC1 = new Hashtable();
tablaRFC1.Add("&", 10);
tablaRFC1.Add("Ñ", 10);
tablaRFC1.Add("A", 11);
tablaRFC1.Add("B", 12);
tablaRFC1.Add("C", 13);
tablaRFC1.Add("D", 14);
tablaRFC1.Add("E", 15);
tablaRFC1.Add("F", 16);
tablaRFC1.Add("G", 17);
tablaRFC1.Add("H", 18);
tablaRFC1.Add("I", 19);
tablaRFC1.Add("J", 21);
tablaRFC1.Add("K", 22);
tablaRFC1.Add("L", 23);
tablaRFC1.Add("M", 24);
tablaRFC1.Add("N", 25);
tablaRFC1.Add("O", 26);
tablaRFC1.Add("P", 27);
tablaRFC1.Add("Q", 28);
tablaRFC1.Add("R", 29);
tablaRFC1.Add("S", 32);
tablaRFC1.Add("T", 33);
tablaRFC1.Add("U", 34);
tablaRFC1.Add("V", 35);
tablaRFC1.Add("W", 36);
tablaRFC1.Add("X", 37);
tablaRFC1.Add("Y", 38);
tablaRFC1.Add("Z", 39);
tablaRFC1.Add("0", 0);
tablaRFC1.Add("1", 1);
tablaRFC1.Add("2", 2);
tablaRFC1.Add("3", 3);
tablaRFC1.Add("4", 4);
tablaRFC1.Add("5", 5);
tablaRFC1.Add("6", 6);
tablaRFC1.Add("7", 7);
tablaRFC1.Add("8", 8);
tablaRFC1.Add("9", 9);
#endregion

#region TablaRFC 2
Hashtable tablaRFC2 = new Hashtable();
tablaRFC2.Add(0, "1");
tablaRFC2.Add(1, "2");
tablaRFC2.Add(2, "3");
tablaRFC2.Add(3, "4");
tablaRFC2.Add(4, "5");
tablaRFC2.Add(5, "6");
tablaRFC2.Add(6, "7");
tablaRFC2.Add(7, "8");
tablaRFC2.Add(8, "9");
tablaRFC2.Add(9, "A");
tablaRFC2.Add(10, "B");
tablaRFC2.Add(11, "C");
tablaRFC2.Add(12, "D");
tablaRFC2.Add(13, "E");
tablaRFC2.Add(14, "F");
tablaRFC2.Add(15, "G");
tablaRFC2.Add(16, "H");
tablaRFC2.Add(17, "I");
tablaRFC2.Add(18, "J");
tablaRFC2.Add(19, "K");
tablaRFC2.Add(20, "L");
tablaRFC2.Add(21, "M");
tablaRFC2.Add(22, "N");
tablaRFC2.Add(23, "P");
tablaRFC2.Add(24, "Q");
tablaRFC2.Add(25, "R");
tablaRFC2.Add(26, "S");
tablaRFC2.Add(27, "T");
tablaRFC2.Add(28, "U");
tablaRFC2.Add(29, "V");
tablaRFC2.Add(30, "W");
tablaRFC2.Add(31, "X");
tablaRFC2.Add(32, "Y");
#endregion

#region TablaRFC 3
Hashtable tablaRFC3 = new Hashtable();
tablaRFC3.Add("A", 10);
tablaRFC3.Add("B", 11);
tablaRFC3.Add("C", 12);
tablaRFC3.Add("D", 13);
tablaRFC3.Add("E", 14);
tablaRFC3.Add("F", 15);
tablaRFC3.Add("G", 16);
tablaRFC3.Add("H", 17);
tablaRFC3.Add("I", 18);
tablaRFC3.Add("J", 19);
tablaRFC3.Add("K", 20);
tablaRFC3.Add("L", 21);
tablaRFC3.Add("M", 22);
tablaRFC3.Add("N", 23);
tablaRFC3.Add("O", 25);
tablaRFC3.Add("P", 26);
tablaRFC3.Add("Q", 27);
tablaRFC3.Add("R", 28);
tablaRFC3.Add("S", 29);
tablaRFC3.Add("T", 30);
tablaRFC3.Add("U", 31);
tablaRFC3.Add("V", 32);
tablaRFC3.Add("W", 33);
tablaRFC3.Add("X", 34);
tablaRFC3.Add("Y", 35);
tablaRFC3.Add("Z", 36);
tablaRFC3.Add("0", 0);
tablaRFC3.Add("1", 1);
tablaRFC3.Add("2", 2);
tablaRFC3.Add("3", 3);
tablaRFC3.Add("4", 4);
tablaRFC3.Add("5", 5);
tablaRFC3.Add("6", 6);
tablaRFC3.Add("7", 7);
tablaRFC3.Add("8", 8);
tablaRFC3.Add("9", 9);
tablaRFC3.Add("", 24);
tablaRFC3.Add(" ", 37);
#endregion

#endregion

//agregamos un cero al inicio de la representación númerica del nombre
nombreEnNumero.Append("0");

//Recorremos el nombre y vamos convirtiendo las letras en
//su valor numérico
foreach (char c in nombreCompleto)
{
if (tablaRFC1.ContainsKey(c.ToString()))
nombreEnNumero.Append(tablaRFC1[c.ToString()].ToString());
else
nombreEnNumero.Append("00");
}

//Calculamos la suma de la secuencia de números
//calculados anteriormente
//la formula es:
//( (el caracter actual multiplicado por diez)
//mas el valor del caracter siguiente )
//(y lo anterior multiplicado por el valor del caracter siguiente)
for (int i = 0; i < nombreEnNumero.Length - 1; i++)
{
valorSuma += ((Convert.ToInt32(nombreEnNumero[i].ToString()) * 10) + Convert.ToInt32(nombreEnNumero[i + 1].ToString())) * Convert.ToInt32(nombreEnNumero[i + 1].ToString());
}

//Lo siguiente no se porque se calcula así, es parte del algoritmo.
//Los magic numbers que aparecen por ahí deben tener algún origen matemático
//relacionado con el algoritmo al igual que el proceso mismo de calcular el
//digito verificador.
//Por esto no puedo añadir comentarios a lo que sigue, lo hice por acto de fe.

int div = 0, mod = 0;
div = Convert.ToInt32(valorSuma) % 1000;
mod = div % 34;
div = (div - mod) / 34;

int indice = 0;
string hc = String.Empty; //los dos primeros caracteres de la homoclave
while (indice <= 1)
{
if (tablaRFC2.ContainsKey((indice == 0) ? div : mod))
hc += tablaRFC2[(indice == 0) ? div : mod];
else
hc += "Z";
indice++;
}

//Agregamos al RFC los dos primeros caracteres de la homoclave
rfc += hc;

//Aqui empieza el calculo del digito verificador basado en lo que tenemos del RFC
//En esta parte tampoco conozco el origen matemático del algoritmo como para dar
//una explicación del proceso, así que ¡tengamos fe hermanos!.
int rfcAnumeroSuma = 0, sumaParcial = 0;
for (int i = 0; i < rfc.Length; i++)
{
if (tablaRFC3.ContainsKey(rfc[i].ToString()))
{
rfcAnumeroSuma = Convert.ToInt32(tablaRFC3[rfc[i].ToString()]);
sumaParcial += (rfcAnumeroSuma * (14 - (i + 1)));
}
}

int moduloVerificador = sumaParcial % 11;
if (moduloVerificador == 0)
rfc += "0";
else
{
sumaParcial = 11 - moduloVerificador;
if (sumaParcial == 10)
rfc += "A";
else
rfc += sumaParcial.ToString();
}

//en este punto la variable rfc pasada ya debe tener la homoclave
//recuerda que la variable rfc se paso como "ref string" lo cual
//hace que se modifique la original.
}

/// <summary>
/// Verifica si el caracter pasado es una vocal
/// </summary>
/// <param name="letra">Caracter a comprobar</param>
/// <returns>Regresa true si es vocal, de lo contrario false</returns>
static private bool EsVocal(char letra)
{
//Aunque para el caso del RFC cambié todas las letras a mayúsculas
//igual agregé las minúsculas.
if (letra == 'A' || letra == 'E' || letra == 'I' || letra == 'O' || letra == 'U' ||
letra == 'a' || letra == 'e' || letra == 'i' || letra == 'o' || letra == 'u')
return true;
else
return false;
}

/// <summary>
/// Remplaza los artículos comúnes en los apellidos en México con caracter vacío (String.Empty).
/// </summary>
/// <param name="palabra">Palabra que se le quitaran los artículos</param>
/// <returns>Regresa la palabra sin los artículos</returns>
static private string QuitarArticulos(string palabra)
{
return palabra.Replace("DEL ", String.Empty).Replace("LAS ", String.Empty).Replace("DE ", String.Empty).Replace("LA ", String.Empty).Replace("Y ", String.Empty).Replace("A ", String.Empty);
}
}
saludos.
Responder Con Cita