Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Generador de RFCs

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Tips & Tricks
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Generador de RFCs Responder citando

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
Ver perfil de usuario Enviar mensaje privado MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: falta la funcion obtieneLetras Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
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


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.