 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Neko++ Cdt


Registrado: 04 Oct 2004Mensajes: 8Ubicación: Cuernavaca, Morelos. México
|
Publicado: Jue 01 Mar, 2007 11:12 pm Asunto: Generador de RFCs |
|
|
Qué tal, les dejo el código para calcular el RFC con homoclave y dígito verificador.
Me basé de varios programas y códigos que andan en la red.
No lo he probado bien, pues lo acabo de terminar ya que es pa' un proyecto urgente (pero si funcia con los primeros que probé).
Pueden pasarlo a una DLL pa' que sea más fácil.
Por fa' si pueden comentarme las mejoras se los agradeceré.
La forma de llamar la función es:
| Código: |
// ESTA SERÍA LA POSIBLE SECCIÓN DEL CODIGO QUE LLAMA A LA DLL
char nombre[61];
char paterno[61];
char materno[61];
char nacimiento[11];
char rfc[14];
/*
AQUI SE ASUME QUE SE VALIDA CADA UNO DE LOS CAMPOS:
LOS NOMBRES NO DEBEN CONTENER ACENTOS NI CARACTERES ESPECIALES
LA FECHA DEBE SER VÁLIDA
*/
strcpy(nombre, edtNombre->Text.c_str());
strcpy(paterno, edtAPaterno->Text.c_str());
strcpy(materno, edtAMaterno->Text.c_str());
strcpy(nacimiento, medtFNacimiento->Text.c_str());
// AQUI LLAMAN A LA FUNCIÓN DE LA DLL
Genera_RFC(paterno, materno, nombre, nacimiento, rfc);
// EL RESULTADO LO GUARDA EN LA VARIABLE rfc
edtRFC->Text = AnsiString(rfc);
/**********************************************
AQUI VA EL CÓDIGO DEL ARCHIVO .H DE LA DLL
SE DEBE LLAMAR GENERARFC.H
**********************************************/
#ifndef __GENERARFC_H
#define __GENERARFC_H
extern "C" void __export __pascal Genera_RFC (
char *paterno,
char *materno,
char *nombre,
char *nacimiento,
char *rfc);
// SE ENCARGA DE EXTRAER LOS CARACTERES 5 AL 10
// BASADOS EN LA FECHA DE NACIMIENTO
AnsiString obtieneFNacimiento(AnsiString fnacimiento);
// VALIDA QUE EL NOMBRE SEA LO SUFICIENTEMENTE LARGO
unsigned int longitudNombre(AnsiString apaterno, AnsiString amaterno, AnsiString nombre);
// ELIMINA LOS ARTICULOS DEL NOMBRE DE LA PERSONA
AnsiString eliminaArticulos(AnsiString elemento);
// ELIMINA NOMBRES NO PERMITIDOS
AnsiString eliminaNombres(AnsiString elemento);
// ELIMINA LAS LETRAS DOBLES CH Y LL
AnsiString eliminaLetrasDobles(AnsiString elemento);
// CALCULA LAS 4 PRIMERAS LETRAS DEL RFC
AnsiString obtieneLetras(AnsiString apaterno, AnsiString amaterno, AnsiString nombre);
// EXTRAE LA PRIMER VOCAL INTERNA DE UN ELEMENTO
AnsiString extraeVocal(AnsiString elemento);
// OBTIENE LA HOMOCLAVE TOMANDO COMO BASE EL NOMBRE COMPLETO
AnsiString obtieneHomoclave(AnsiString apaterno, AnsiString amaterno, AnsiString nombre);
// VALIDA QUE LOS CUATRO PRIMEROS DÍGITOS DEL RFC NO SEAN PALABRAS INVÁLIDAS
AnsiString esValido(AnsiString cadena);
// OBTIENE EL DIGITO VERIFICADOR A PARTIR DEL RFC A 12 CARACTERES
AnsiString obtieneDigito(AnsiString rfcTemporal);
#endif
/**********************************************
AQUI VA EL CÓDIGO DEL ARCHIVO .CPP DE LA DLL
SE DEBE LLAMAR GENERARFC.CPP
**********************************************/
//---------------------------------------------------------------------------
#include <vcl>
#include <windows>
#pragma hdrstop
#include "GeneraRFC.h"
#include <string>
#define SIN_ERROR 0
#define NOMB_INVALIDO 1
#define SIN_NOMBRE 2
//---------------------------------------------------------------------------
const AnsiString Articulos[6] = {"DE ", "DEL ", "LA ", "LAS ", "LOS ", "Y "};
const unsigned int numArticulos = 6;
const AnsiString Nombres[2] = {"JOSE ", "MARIA "};
const unsigned int numNombres = 2;
const AnsiString Malas[] = { "BUEI", "BUEY", "CACA", "CACO", "CAGA", "CAGO", "CAKA", "CAKO", "COGE", "COJA",
"COJE", "COJI", "COJO", "CULO", "FETO", "GUEY", "JOTO", "KACA", "KACO", "KAGA",
"KAGO", "KOGE", "KOJO", "KAKA", "KULO", "LOCA", "LOCO", "LOKA", "LOKO", "MAME",
"MAMO", "MEAR", "MEAS", "MEON", "MION", "MOCO", "MULA", "PEDA", "PEDO", "PENE",
"PUTA", "PUTO", "QULO", "RATA", "RUIN"};
const unsigned int numMalas = 45;
// NECESARIOS PARA FORMAR LA CADENA CODIFICADA Y EL DÍGITO VERIFICADOR
const AnsiString Caracteres = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ-";
const AnsiString Valor[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
"30", "31", "32", "33", "34", "35", "36", "37"};
// NECESARIOS PARA GENERAR LA HOMOCLAVE
const AnsiString ValorH[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
"11", "12", "13", "14", "15", "16", "17", "18", "19", "21",
"22", "23", "24", "25", "10", "26", "27", "28", "29", "32",
"33", "34", "35", "36", "37", "38", "39"};
const AnsiString ValorU[] = {"00", "00", "01", "02", "03", "04", "05", "06", "07", "08",
"09", "10", "11", "12", "13", "14", "15", "16", "17", "18",
"19", "20", "21", "22", " ", "00", "23", "24", "25", "26",
"27", "28", "29", "30", "31", "32", "33"};
const unsigned int numValores = 37;
const unsigned int numCaracteres = 38;
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
// FUNCIÓN DE LLAMADA
extern "C" void __export __pascal Genera_RFC(
char *paterno,
char *materno,
char *nombre,
char *nacimiento,
char *rfc){
AnsiString nContribuyente, tmpNombre;
AnsiString aPaterno, tmpAPat;
AnsiString aMaterno, tmpAMat;
AnsiString fNacimiento;
AnsiString rfcValido;
nContribuyente = AnsiString(nombre);
aPaterno = AnsiString(paterno);
aMaterno = AnsiString(materno);
fNacimiento = AnsiString(nacimiento);
nContribuyente = nContribuyente.Trim();
aPaterno = aPaterno.Trim();
aMaterno = aMaterno.Trim();
unsigned int estado;
// REGLA 0. EL NOMBRE COMPLETO NO DEBE SER VACÍO
// REGLA 0.1 EL NOMBRE NO PUEDE SER VACÍO
estado = longitudNombre(aPaterno, aMaterno, nContribuyente);
if(estado){
itoa(estado+48, rfc, 10);
return;
}
// REGLA 1. ELIMINAR LOS ARTÍCULOS DEL NOMBRE COMPLETO
tmpAPat = eliminaArticulos(aPaterno);
tmpAMat = eliminaArticulos(aMaterno);
tmpNombre = eliminaArticulos(nContribuyente);
// REGLA 2. ELIMINAR "JOSE" Y/O "MARÍA" DE LOS NOMBRES COMPUESTOS
// REGLA 2.1. SI EL NOMBRE COMPUESTO ES "JOSE MARIA", SE TOMA "MARIA" COMO NOMBRE
// SUCEDE LO MISMO PARA NOMBRE SIMILARES
tmpNombre = eliminaNombres(tmpNombre);
// LA SIGUIENTE REGLA YA NO APLICA
//************************************************************************************
// REGLA 3. ELIMINAR LETRAS DOBLES DEL INICIO DE LOS APELLIDOS Y DEL NOMBRE
// tmpAPat = eliminaLetrasDobles(tmpAPat);
// tmpAMat = eliminaLetrasDobles(tmpAMat);
// tmpNombre = eliminaLetrasDobles(tmpNombre);
//************************************************************************************
// REGLA 4. OBTENER CUATRO CARACTERES DEL NOMBRE COMPLETO
//
// REGLA 4.1. SI AMBOS APELLIDOS SON "", SE TOMAN LOS DOS PRIMEROS DEL NOMBRE Y SE REPITEN
// EJEMPLO: "" + "" + "FRANCISCO" ==> "FRFR"
//
// REGLA 4.2. SI EL APELLIDO PATERNO ES "", SE OBTIENE DEL APELLIDO MATERNO LA PRIMERA LETRA
// Y LA PRIMERA VOCAL INTERNA, EL TERCERACTER SERÁ UNA "X", DEL NOMBRE SE OBTIENEN
// LA PRIMER LETRA
// EJEMPLO: "" + "CRUZ" + "FRANCISCO" ==> "CUXF"
// REGLA 4.2.1. SI EL APELLIDO MATERNO ES MENOR A 3 CARACTERES, SE TOMA LA PRIMERA LETRA, LA SEGUNDA
// SERÁ UNA "X", SEGUIDO DE LOS DOS PRIMEROS CARACTERES DEL NOMBRE
// EJEMPLO: "" + "LU" + "FRANCISCO" ==> "LXFR"
//
// REGLA 4.3. SI EL APELLIDO MATERNO ES "", SE OBTIENE DEL APELLIDO PATERNO LA PRIMERA LETRA
// Y LA PRIMERA VOCAL INTERNA, EL TERCERACTER SERÁ UNA "X", DEL NOMBRE SE OBTIENEN
// LA PRIMER LETRA
// EJEMPLO: "CRUZ" + "" + "FRANCISCO" ==> "CUXF"
// REGLA 4.3.1. SI EL APELLIDO PATERNO ES MENOR A 3 CARACTERES, SE TOMA LA PRIMERA LETRA, LA SEGUNDA
// SERÁ UNA "X", SEGUIDO DE LOS DOS PRIMEROS CARACTERES DEL NOMBRE
// EJEMPLO: "LU" + "" + "FRANCISCO" ==> "LXFR"
//
// REGLA 4.4. SI EL APELLIDO PATERNO ES MENOR A 3 CARACTERES, SE OBTIENE LA PRIMERA LETRA
// LA SEGUNDA LETRA SERÁ LA PRIMERA DEL APELLIDO MATERNO, SEGUIDO DE LOS DOS
// PRIMEROS DEL NOMBRE
// EJEMPLO: "LU" + "ORTIZ" + "FRANCISCO" ==> "LOFR"
//
// REGLA 4.5. EN CASO DE QUE NO APLIQUE NINGUNA DE LAS SUBREGLAS ANTERIORES, SE TOMA LA PRIMERA
// LETRA DEL APELLIDO PATERNO, LA PRIMERA VOCAL INTERNA DEL MISMO, LA PRIMERA LETRA
// DEL APELLIDO MATERNO Y LA PRIMERA LETRA DEL NOMBRE
// EJEMPLO: "OROZCO" + "CABRERA" + "FRANCISCO" ==> "00CF"
//
// REGLA 4.5.1. SI EL APELLIDO PATERNO NO CONTIENE VOCALES INTERNAS, SE TOMA LA SEGUNDA LETRA DE ÉSTE
//
rfcValido = obtieneLetras(tmpAPat, tmpAMat, tmpNombre);
// REGLA 5. LAS CUATRO LETRAS GENERADAS NO DEBEN REPRESENTAR UN INSULTO PARA EL CONTRIBUYENTE,
// SI ES ASÍ, SE CAMBIA EL CUARTO CARACTER POR UNA "X"
rfcValido = esValido(rfcValido);
// REGLA 6. DE LA FECHA DE NACIMIENTO, SE OBTIENEN LOS ULTIMOS 2 DIGITOS DEL AÑO,
// LOS DOS DEL MES Y LOS DOS DEL DÍA
rfcValido += obtieneFNacimiento(fNacimiento);
// REGLA 7. OBTENER LA HOMOCLAVE TOMANDO EN CUENTA EL NOMBRE MODIFICADO DEL CONTRIBUYENTE
rfcValido += obtieneHomoclave(aPaterno, aMaterno, nContribuyente);
// REGLA 8. OBTENER EL DÍGITO VERIFICADOR
rfcValido += obtieneDigito(rfcValido);
strcpy(rfc, rfcValido.c_str());
return;
}
AnsiString obtieneFNacimiento(AnsiString fnacimiento){
AnsiString digitos;
digitos = fnacimiento.SubString(9,2) + fnacimiento.SubString(4,2) + fnacimiento.SubString(1,2);
return digitos;
}
unsigned int longitudNombre(AnsiString apaterno, AnsiString amaterno, AnsiString nombre){
AnsiString nombreCompleto = apaterno + " " + amaterno + " " + nombre;
if(nombreCompleto.Length() <= 6){
return NOMB_INVALIDO;
}
if(!nombre.Length())
return SIN_NOMBRE;
return SIN_ERROR;
}
AnsiString eliminaArticulos(AnsiString elemento){
AnsiString tmpElemento;
tmpElemento = elemento;
int posicion = 1;
for(int indice = 1; indice <= numArticulos; indice++){
do{
posicion = tmpElemento.Pos(Articulos[indice]);
if(posicion){
tmpElemento = tmpElemento.Delete(posicion, Articulos[indice].Length());
}
}while(posicion);
}
return tmpElemento;
}
AnsiString eliminaNombres(AnsiString elemento){
AnsiString tmpElemento;
tmpElemento = elemento;
int posicion = 1;
for(int indice = 1; indice <numNombres> 3){
primero = amaterno.SubString(1,1);
segundo = extraeVocal(amaterno);
tercero = "X";
}
// SE ASUME QUE APATERNO ES ""
if(amaterno.Length() && amaterno.Length() <3> 3){
primero = apaterno.SubString(1,1);
segundo = extraeVocal(apaterno);
tercero = "X";
}
// SE ASUME QUE AMATERNO ES ""
if(apaterno.Length() && apaterno.Length() < 3){
primero = apaterno.SubString(1,1);
segundo = "X";
}
// SI AMBOS APELLIDOS SON "" LA INICIALIZACIÓN DE LAS VARIABLES CONTEMPLA EL
// ELSE O CONDICIÓN FINAL
}
else {
if(apaterno.Length()< 3){
primero = apaterno.SubString(1,1);
segundo = amaterno.SubString(1,1);
}
else {
primero = apaterno.SubString(1,1);
segundo = extraeVocal(apaterno);
tercero = amaterno.SubString(1,1);
cuarto = nombre.SubString(1,1);
}
}
return primero + segundo + tercero + cuarto;
}
AnsiString extraeVocal(AnsiString elemento){
AnsiString letra;
unsigned int posicion;
AnsiString vocales = "AEIOU";
letra = elemento.SubString(2,1);
for(int indice = 2; indice <= elemento.Length(); indice ++){
posicion = vocales.Pos(elemento.SubString(indice, 1));
if(posicion){
letra = elemento.SubString(indice, 1);
break;
}
}
return letra;
}
AnsiString obtieneHomoclave(AnsiString apaterno, AnsiString amaterno, AnsiString nombre){
AnsiString homoclave;
AnsiString valores;
AnsiString nomCompleto;
AnsiString varDigitos;
unsigned int posicion;
int suma;
int residuo;
int cociente;
int tresDigitos;
valores = "0";
nomCompleto = apaterno + " " + amaterno + " " + nombre;
AnsiString caracter;
// CONVIERTE EL NOMBRE EN UNA CADENA CODIFICADA
for(int indice = 1; indice <= nomCompleto.Length(); indice++){
caracter = nomCompleto.SubString(indice, 1);
posicion = Caracteres.Pos(caracter);
if(posicion){
valores += ValorH[posicion-1];
}
else{
valores += "00";
}
}
// CONVIERTE LA CADENA CODIFICADA EN UN NÚMERO ENTERO
suma = 0;
for(int indice = 1; indice < valores.Length(); indice++){
int factor1 = valores.SubString(indice, 2).ToInt();
int factor2 = valores.SubString(indice+1, 1).ToInt();
suma += factor1 * factor2;
}
// OBTIENE LOS TRES ÚLTOMOS DÍGITOS
tresDigitos = suma%1000;
// OBTIENE EL COCIENTE 34 DE LOS 3 DIGITOS
cociente = tresDigitos/34;
// OBTIENE EL RESIDUO 34 DE LOS 3 DIGITOS
residuo = tresDigitos%34;
varDigitos = AnsiString(cociente);
if(cociente == 0){
homoclave = "1";
}
else {
if(cociente < 10){
varDigitos = varDigitos.Insert("0", 1);
}
// LOCALIZA EN QUÉ POSICIÓN SE ENCUENTRAN LOS DÍGITOS DEL COCIENTE
for(posicion = 0; posicion < numValores; posicion++){
if(varDigitos == ValorU[posicion]){
break;
}
}
posicion++;
if(posicion){
homoclave = Caracteres.SubString(posicion,1);
}
else{
homoclave = "1";
}
}
// LOCALIZA EN QUÉ POSICIÓN SE ENCUENTRAN LOS DÍGITOS DEL RESIDUO
varDigitos = AnsiString(residuo);
if(residuo == 0){
homoclave += "1";
}
else{
if(residuo < 10){
varDigitos = varDigitos.Insert("0", 1);
}
for(posicion = 0; posicion < numValores; posicion++){
if(varDigitos == ValorU[posicion]){
break;
}
}
posicion++;
if(posicion){
homoclave += Caracteres.SubString(posicion,1);
}
else{
homoclave += "1";
}
}
return homoclave;
}
// ESTA FUNCIÓN CAMBIA LAS PALABRAS QUE PUEDAN SONAR OFENSIVAS PARA EL CONTRIBUYENTE
AnsiString esValido(AnsiString cadena){
for(int indice = 1; indice <= numMalas; indice++){
if(!cadena.AnsiCompare(Malas[indice])){
cadena.Insert("X", 4);
break;
}
}
return cadena;
}
AnsiString obtieneDigito(AnsiString rfcTemporal){
AnsiString digito;
AnsiString valores;
AnsiString varDigitos;
int posicion;
int suma;
int cociente;
int variable;
int factor1;
int valDigito;
valores = "";
AnsiString caracter;
suma = 0;
variable = 13;
// CONVIERTE EL RFC, LOS 12 CARACTERES ACTUALES, EN UN VALOR BASADO EN SUS COMPONENTES
for(int indice = 1; indice <= rfcTemporal.Length(); indice++){
caracter = rfcTemporal.SubString(indice, 1);
if(caracter == " "){
caracter = "-";
}
posicion = Caracteres.Pos(caracter);
if(posicion){
factor1 = Valor[posicion-1].ToInt();
}
else{
factor1 = 0;
}
suma += factor1*variable;
variable--;
}
// OBTIENE EL VALOR POSIBLE PARA EL DIGITO VERIFICADOR
valDigito = 11 - (suma%11);
switch(valDigito){
case 10: digito = "A";
break;
case 11: digito = "0";
break;
default: digito = AnsiString(valDigito);
}
return digito;
}
|
Disculpen que meta todo el código aquí pero no sé como pictes adjuntar archivos jajajajajaja
OK Saludos.
/**********************************/
Tito Ruiz Sánchez |
|
| Volver arriba |
|
 |
max Lt

Registrado: 12 Mar 2005Mensajes: 89Ubicación: Argentina Prov B.A Mar del Plata
|
Publicado: Mie 14 Mar, 2007 4:30 pm Asunto: |
|
|
holas disculpa mi preguntonta....pero... que es RFC por que no entendi bien el coigo .que es lo q hace..y para q sirve _________________ Salu2 |
|
| Volver arriba |
|
 |
Buildero Master


Registrado: 23 Dic 2003Mensajes: 523Ubicación: Puebla, México
|
Publicado: Mie 14 Mar, 2007 5:03 pm Asunto: |
|
|
Que tal Max, pues resulta que a nuestro compañero Neko++ se le olvido mencionar que el RFC sólo aplica en México.
El RFC es el Registro Federal de Contribuyentes, es una clave de identificación tributaria que utilizamos en México.
En tu caso, que eres de Argentina, si no me equivoco le llaman CUIT (Código Único de Identificación Tributaria).
Saludos! _________________ Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida. |
|
| Volver arriba |
|
 |
grz47 Ens


Registrado: 05 Ago 2005Mensajes: 40Ubicación: SINALOA, MEXICO
|
Publicado: Jue 17 Dic, 2015 12:44 am Asunto: falta la funcion obtieneLetras |
|
|
buenas tardes
estaba checando tu código y hace falta una función llamada obtieneLetras, si la podrías anexar por favor
saludos _________________ GRZ 47 |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|