Foros del Web

Foros del Web (http://www.forosdelweb.com/)
-   Programación General (http://www.forosdelweb.com/f14/)
-   -   Alguien tiene el algoritmo para obtener R.F.C. Mexicano con todo y homoclave ? (http://www.forosdelweb.com/f14/alguien-tiene-algoritmo-para-obtener-r-f-c-mexicano-con-todo-homoclave-317714/)

webbeginner 18/07/2005 14:43

Alguien tiene el algoritmo para obtener R.F.C. Mexicano con todo y homoclave ?
 
Esa es mi pregunta.

Si alguien tiene el algoritmo o mejor aun el codigo de algun programa que obtenga el R.F.C. (Registro Federal de Contribuyentes) que incluya la homoclave (la homoclave son los ultimos 3 caracteres del RFC, y es para evitar duplicidad de RFC en caso de las personas que nacieron el mismo día y por coincdencia se llamen igual.

Gracias

blackwind 18/07/2005 21:53

yo hice un programa que obtenia el RFC pero SIN la homoclave. Como se supone que se obtiene la homoclave??, siempre he tenido esa duda.....

por cierto, para hacerlo sin la homoclave es muy sencillo, recuerdo que fue de mis primeras tareas cuando estaba en mi primera clase de programacion, no te deberia de causar mucho problema......
p.d: ¿ en que lenguaje?

Myakire 20/07/2005 12:35

La única forma de obtener la homoclave sin buscarlo previamente en alguna BD, es que el usuario te la diga.

RootK 20/07/2005 12:55

Cita:

La única forma de obtener la homoclave sin buscarlo previamente en alguna BD, es que el usuario te la diga.
Así es.. de hecho la homoclave te la asigna hacienda.. tu no puedes obtenerla propiamente (hasta donde yo sé..)

Y tambien es importante saber en que lenguaje lo deseas desarrollar

Salu2

blackwind 20/07/2005 13:34

Ya decia yo que era extraño, esos ultimos 3 digitos nunca les he visto logica.......

cesar_nava 20/07/2005 14:02

Solo para aclararles.

Si se puede obtener la homoclave del R. F. C., solo tienen que solicitarle el algoritmo a Hacienda (se los proporcionan gratuito).

De hecho, Hacienda tambien les puede proporcionar el algoritmo para obtener el C. U. R. P.

Aqui les dejo el enlace a un programa que les obtiene el RFC (con todo y homoclave):

http://www.aplicarh.com/Descargas/utlfree/CalcRFC.exe

Aqui otro a un programa que les obtiene el CURP:

http://www.aplicarh.com/Descargas/utlfree/CalcCURP.exe

RootK 20/07/2005 15:24

Cita:

Si se puede obtener la homoclave del R. F. C., solo tienen que solicitarle el algoritmo a Hacienda (se los proporcionan gratuito).
mm.... :arriba: .gracias por la aclaración cesar_nava.. lo que uno sigue aprendiedo por estos lares..(y quien iba a pensar que en un foro de programacion.. jeje :risa: ) ..., sinceramente no sabía que uno mismo pudiera sacar su homoclave... la verdad si estaría interesado en conseguir el algoritmo.. ya por cuestiones de aprendisaje.. :-D

blackwind 20/07/2005 20:35

ok rootk, si lo logras encontrar, pubicalo no?, a mi tambien me da mucha curiosidad.......

RootK 20/07/2005 20:53

Cita:

si lo logras encontrar, pubicalo no?, a mi tambien me da mucha curiosidad.......
Claro que si friend.. de hecho , estaba pensando en encotrarle la lógica que maneja y buscar la manera de yo implementarlo..

O porque no lo metemos como parte del taller de programacion... jeje.. no estaría mal .. un programa que calcule el RFC y/o CURP..., el problema del RFC viene a partir de la homoclave . :pensando: . porque las primeras palabras y letras se forma conforme a tu nombre y de la CURP... lo unico que me falta por sacar es el último dígito...

RFC:
se forma por las primeras 2 letras de tu apellido, despues la primera letra de tu segundo apellido, y la primera letra de tu primer nombre.. luego el año de nacimiento, mes y día (de 2 digitos..) pero la homoclave..?? :pensando:

Ejemplo
Juan Pérez Pérez que nacio el 20 de Julio de 1973
RFC= PEPJ730720 - ??? (y la homoclave )

P.D.- Se que a lo mejor estoy offtopic. :borracho: . pero ya sabemos que especialmente en éste foro de repente de una cosa salen otras.. pero claro que todo es con el fin de aprender.. :-D

blackwind 20/07/2005 21:15

es buena idea .... PERO, para poderla llevar a cabo deberiamos de tener varios RFC de referencia, porque asi de la nada va a estar muuuy dificil.....

RootK 21/07/2005 09:46

Cita:

para poderla llevar a cabo deberiamos de tener varios RFC de referencia, porque asi de la nada va a estar muuuy dificil.....
Pues no creo que los necesitemos.. podemos estar jugando con los archivos que envió cesar_nava para sacar los datos... y eso tomarlo como base e irlo comparando con nuestro programa no crees..??

blackwind 21/07/2005 14:40

podria ser........jejeje

Myakire 22/07/2005 11:10

Cierto, no lo sabía.

Depues de verificar que el programa efectivamente funciona. Me puse a buscar algo en internet.
Despues de asquearme de tantos y tantos sujetos que cobran 100 pesos en promedio por cada dato que con los programas anteriores gratuitamente se obtienen, y de postear la liga que cesar_nava proporcionó en igual número de sitios. Encontré un SP que funciona sin problemas para las personas físicas:

Se los dejo en DOS post, por que excede los 10000 caracteres por mensaje.

primera parte:
Código:

CREATE PROCEDURE SP_CALCULA_RFC
@NOMBRES_AUX VARCHAR(100),
@APATERNO_AUX VARCHAR(100),
@AMATERNO_AUX VARCHAR(100),
@FECHANACIMIENTO DATETIME,
@RFC_OUT CHAR(16) OUT
AS
--DECLARACION DE VARIABLES
DECLARE @NOMBRES VARCHAR(100)
DECLARE @APATERNO VARCHAR(100)
DECLARE @AMATERNO VARCHAR(100)
DECLARE @T_NOMTOT CHAR(52)
DECLARE @NOMBRE1 VARCHAR(100) --PRIMER NOMBRE
DECLARE @NOMBRE2 VARCHAR(100) --DEMAS NOMBRES
DECLARE @NOMBRES_LONGITUD INT --LONGITUD DE TODOS @NOMBRES
DECLARE @NOMBRE1_LONGITUD INT --LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
DECLARE @APATERNO1 VARCHAR(100) --PRIMER NOMBRE
DECLARE @APATERNO2 VARCHAR(100) --DEMAS NOMBRES
DECLARE @APATERNO_LONGITUD INT --LONGITUD DE TODOS @NOMBRES
DECLARE @APATERNO1_LONGITUD INT --LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
DECLARE @AMATERNO1 VARCHAR(100) --PRIMER NOMBRE
DECLARE @AMATERNO2 VARCHAR(100) --DEMAS NOMBRES
DECLARE @AMATERNO_LONGITUD INT --LONGITUD DE TODOS @NOMBRES
DECLARE @AMATERNO1_LONGITUD INT --LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
DECLARE @VARLOOPS INT --VARIABLE PARA LOS LOOPS, SE INICIALIZA AL INICIR UN LOOP
DECLARE @RFC CHAR(16)
DECLARE @T_NOMNUM CHAR(102) --Nombre numerico
DECLARE @T_SUMA INT
DECLARE @T_DIVID INT -- Dividendo
DECLARE @T_MOD INT -- MOD de la division
DECLARE @T_HOMOCLV CHAR(3) -- Homoclave
DECLARE @T_NUMERO INT -- Numero ASC asignado a un caracter
DECLARE @T_PARCIAL INT -- Acumulado de la suma de los caracteres del RFC


--INICIALZA VARIABLES
SET @NOMBRES = LTRIM(RTRIM(@NOMBRES_AUX))
SET @APATERNO = LTRIM(RTRIM(@APATERNO_AUX))
SET @AMATERNO = LTRIM(RTRIM(@AMATERNO_AUX))
SET @T_NOMTOT =@APATERNO+' '+@AMATERNO+' '+@NOMBRES

--PROCESAR NOMBRES DE PILA
SET @VARLOOPS = 0
WHILE @VARLOOPS <> 1
BEGIN

SET @NOMBRES_LONGITUD = LEN(@NOMBRES)
SET @NOMBRE1_LONGITUD = PATINDEX('% %',@NOMBRES)

IF @NOMBRE1_LONGITUD = 0
SET @NOMBRE1_LONGITUD = @NOMBRES_LONGITUD

SET @NOMBRE1 = RTRIM(LEFT(@NOMBRES,@NOMBRE1_LONGITUD))
SET @NOMBRE2 = LTRIM(RIGHT(@NOMBRES,@NOMBRES_LONGITUD - @NOMBRE1_LONGITUD))

--SE QUINTAN LOS NOMBRES DE JOSE, MARIA,MA,MA.
IF @NOMBRE1 IN ('JOSE','MARIA','MA.','MA','DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND @NOMBRE2 <> ''
BEGIN
SET @NOMBRES = @NOMBRE2

END
ELSE
BEGIN
SET @VARLOOPS = 1
END
END

--PROCESAMOS APELLIDOS, PATERNO EN UN LOOP
SET @VARLOOPS = 0
WHILE @VARLOOPS <> 1
BEGIN

SET @APATERNO_LONGITUD = LEN(@APATERNO)
SET @APATERNO1_LONGITUD = PATINDEX('% %',@APATERNO)

IF @APATERNO1_LONGITUD = 0
SET @APATERNO1_LONGITUD = @APATERNO_LONGITUD

SET @APATERNO1 = RTRIM(LEFT(@APATERNO,@APATERNO1_LONGITUD))
SET @APATERNO2 = LTRIM(RIGHT(@APATERNO,@APATERNO_LONGITUD - @APATERNO1_LONGITUD))

--SE QUINTAN LOS SUFIJOS
IF @APATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND @APATERNO2 <> ''
BEGIN
SET @APATERNO = @APATERNO2

END
ELSE
BEGIN
SET @VARLOOPS = 1
END
END

--PROCESAMOS APELLIDOS, MATERNO EN UN LOOP
SET @VARLOOPS = 0
WHILE @VARLOOPS <> 1
BEGIN

SET @AMATERNO_LONGITUD = LEN(@AMATERNO)
SET @AMATERNO1_LONGITUD = PATINDEX('% %',@AMATERNO)

IF @AMATERNO1_LONGITUD = 0
SET @AMATERNO1_LONGITUD = @AMATERNO_LONGITUD

SET @AMATERNO1 = RTRIM(LEFT(@AMATERNO,@AMATERNO1_LONGITUD))
SET @AMATERNO2 = LTRIM(RIGHT(@AMATERNO,@AMATERNO_LONGITUD - @AMATERNO1_LONGITUD))

--SE QUINTAN LOS SUFIJOS
IF @AMATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND @AMATERNO2 <> ''
BEGIN
SET @AMATERNO = @AMATERNO2

END
ELSE
BEGIN
SET @VARLOOPS = 1
END
END

--SE OBTIENE DEL PRIMER APELLIDO LA PRIMER LETRA Y LA PRIMER VOCAL INTERNA
SET @RFC = LEFT(@APATERNO1,1)
SET @APATERNO1_LONGITUD= LEN(@APATERNO1)
SET @VARLOOPS = 1 --EMPIEZA EN UNO POR LA PRIMERA LETRA SE LA VA A SALTAR

WHILE @APATERNO1_LONGITUD > @VARLOOPS
BEGIN
SET @VARLOOPS = @VARLOOPS + 1

IF SUBSTRING(@APATERNO1,@VARLOOPS,1) IN ('A','E','I','O','U')
BEGIN

SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@APATERNO1,@VARLOOPS,1))
SET @VARLOOPS = @APATERNO1_LONGITUD

END

END

--SE OBTIENE LA PRIMER LETRA DEL APELLIDO MATERNO SI NO TIENE APELLIDO MATERNO SE PONE UNA X
--DICE QUE SI NO TIENE APELLIDO MATERNO LE PONGAS LA PRIMER LETRA DEL APELLIDO PATERNO EN EL RFX

IF ISNULL(@AMATERNO1,'') = ''
BEGIN
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@APATERNO1,1,1))
END
ELSE
BEGIN
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@AMATERNO1,1,1))
END
--SE LE AGREGA LA PRIMER LETRA DEL NOMBRE
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@NOMBRE1,1,1))

--CHEAS QUE NO SEA UNA PALARA INCONVENIENTE
/*
IF EXISTS ( SELECT INC_PALINC FROM NINCO WHERE INC_PALINC = @RFC )
BEGIN
SELECT @RFC = LTRIM(RTRIM (SUBSTRING (@RFC , 1 , 3))) + 'X'
END
*/
--SE LE AGREGA LA FECHA DE NACIMIENTO

SET @RFC = RTRIM(@RFC) + CONVERT(CHAR,@FECHANACIMIENTO,12)

--HOMOCLAVE
SET @T_NOMNUM = '0'

--SACA NOMBRE NUMERICO
SET @VARLOOPS = 1
WHILE @VARLOOPS <= 52
BEGIN
SET @T_NOMNUM = LTRIM(RTRIM (@T_NOMNUM)) +
CASE
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS, 1) = 'A' THEN '11'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'B' THEN '12'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'C' THEN '13'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'D' THEN '14'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'E' THEN '15'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'F' THEN '16'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'G' THEN '17'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'H' THEN '18'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'I' THEN '19'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'J' THEN '21'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'K' THEN '22'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'L' THEN '23'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'M' THEN '24'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'N' THEN '25'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'O' THEN '26'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'P' THEN '27'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'Q' THEN '28'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'R' THEN '29'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'S' THEN '32'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'T' THEN '33'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'U' THEN '34'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'V' THEN '35'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'W' THEN '36'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'X' THEN '37'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'Y' THEN '38'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'Z' THEN '39'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) >= '0' AND
SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) <= '9' THEN CONVERT(VARCHAR,CONVERT(INT, SUBSTRING (@T_NOMTOT , @VARLOOPS , 1)) , 2)
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) IN ('&','Ñ') THEN '10'
ELSE '00'
END

SET @VARLOOPS = @VARLOOPS + 1
END
set @VARLOOPS = 1
SET @T_SUMA = 0
while @VARLOOPS <= 99
begin
SET @T_SUMA = @T_SUMA + ((CONVERT(INT,SUBSTRING (@T_NOMNUM , @VARLOOPS , 1))*10) + CONVERT(INT,SUBSTRING (@T_NOMNUM , @VARLOOPS+1 , 1))) * CONVERT(INT,SUBSTRING (@T_NOMNUM , @VARLOOPS+1 , 1))

SET @VARLOOPS = @VARLOOPS + 1
end

-- Obtener HOMOCLAVE

SELECT @T_DIVID = @T_SUMA%1000 -- Obtener residuo de los ultimos 3 digitos
SELECT @T_MOD = @T_DIVID%34 -- Obtener el residuo de los ultimos 3 digitos-- entre 34
SELECT @T_DIVID = (@T_DIVID - @T_MOD) / 34 -- Obtener el Cociente entero
--select @T_DIVID,@T_MOD
-- Checar Cociente y residuo
SET @VARLOOPS = 0

WHILE @VARLOOPS <= 1
BEGIN
SET @T_HOMOCLV =
CASE CASE @VARLOOPS WHEN 0 THEN @T_DIVID ELSE @T_MOD END
WHEN 0 THEN '1'
WHEN 1 THEN '2'
WHEN 2 THEN '3'
WHEN 3 THEN '4'
WHEN 4 THEN '5'
WHEN 5 THEN '6'
WHEN 6 THEN '7'
WHEN 7 THEN '8'
WHEN 8 THEN '9'
WHEN 9 THEN 'A'
WHEN 10 THEN 'B'
WHEN 11 THEN 'C'
WHEN 12 THEN 'D'
WHEN 13 THEN 'E'
WHEN 14 THEN 'F'
WHEN 15 THEN 'G'
WHEN 16 THEN 'H'
WHEN 17 THEN 'I'

WHEN 18 THEN 'J'
WHEN 19 THEN 'K'
WHEN 20 THEN 'L'
WHEN 21 THEN 'M'
WHEN 22 THEN 'N'
WHEN 23 THEN 'P'
WHEN 24 THEN 'Q'
WHEN 25 THEN 'R'
WHEN 26 THEN 'S'
WHEN 27 THEN 'T'
WHEN 28 THEN 'U'
WHEN 29 THEN 'V'
WHEN 30 THEN 'W'
WHEN 31 THEN 'X'
WHEN 32 THEN 'Y'
ELSE 'Z'
END
SET @VARLOOPS = @VARLOOPS + 1
-- Incluir la parte de la homoclave
SET @RFC = LTRIM(RTRIM (@RFC)) + LTRIM(RTRIM (@T_HOMOCLV))
END


Myakire 22/07/2005 11:11

Segunda parte:

Código:

-- ---------------------------------------------
-- Obtener Digito Verificador
-- ---------------------------------------------
SET @VARLOOPS = 0
SET @T_PARCIAL = 0
WHILE @VARLOOPS < 12
BEGIN
SELECT @VARLOOPS = @VARLOOPS + 1
SET @T_NUMERO =
CASE
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'A' THEN 10
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'B' THEN 11
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'C' THEN 12
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'D' THEN 13
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'E' THEN 14
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'F' THEN 15
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'G' THEN 16
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'H' THEN 17
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'I' THEN 18
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'J' THEN 19
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'K' THEN 20
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'L' THEN 21
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'M' THEN 22
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'N' THEN 23
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'O' THEN 25
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'P' THEN 26
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'Q' THEN 27
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'R' THEN 28
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'S' THEN 29
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'T' THEN 30
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'U' THEN 31
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'V' THEN 32
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'W' THEN 33
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'X' THEN 34
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'Y' THEN 35
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = 'Z' THEN 36
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) >= '0' AND
SUBSTRING (@RFC , @VARLOOPS , 1) <= '9'

THEN CONVERT(INT,SUBSTRING (@RFC , @VARLOOPS , 1))
WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = ''

THEN 24

WHEN SUBSTRING (@RFC , @VARLOOPS , 1) = ' '

THEN 37

ELSE 0
END
-- Contabilizar el nuevo digito
SELECT @T_PARCIAL = @T_PARCIAL + (@T_NUMERO * (14 - @VARLOOPS))
END

SET @T_MOD = ROUND(@T_PARCIAL%11,1)
IF @T_MOD = 0

SET @RFC = LTRIM(RTRIM (@RFC)) + '0'
ELSE
BEGIN
SET @T_PARCIAL = 11 - @T_MOD
IF @T_PARCIAL = 10
SELECT @RFC = LTRIM(RTRIM (@RFC)) + 'A'
ELSE
SELECT @RFC = LTRIM(RTRIM (@RFC)) + CONVERT(VARCHAR ,@T_PARCIAL)
END


--SELECT @T_NOMTOT,@T_SUMA

SET @RFC_OUT = @RFC
SELECT @RFC AS 'RFC'

GO

En unos días se los paso en Delphi y ASP.

y aunque este y mucho más fácil e intuitivo. Les dejo el algorítmo del RFC que encontré en el mismo sitio:

Cita:

En este foro vi a una persona que quiere hacer dinero con tal de vender información que es publica para todo mundo pero que es dificil de conseguir....

Es dificil de conseguir precisamente porque hay cuates como este wy que se aprovechan de que tienen un contactito en el SAT y no quieren soltar la sopa con tal de sacar ventaja.

Asi que para evitar este tipo de conflictos, he aqui el algoritmo para el calculo del RFC:

Tomas del Apellido Paterno y eliminas cualquiera de los siguientes articulos:
"Y ", "A ", "DE ", "LA ", "DEL ", "LAS "
De lo que sobra, tomas la primer letra y la primer vocal.

Haces lo mismo con el apellido paterno, pero solo tomas la primer letra, es decir, eliminas los articulos.

Tomas la primer letra del nombre

Tomas las dos cifras del año de nacimiento (por ejemplo: 1976.. tomas 76).

Tomas el numero de mes.

Tomas el numero de dia.

Si naciste en algun dia del 1 al 9, entonces tomas 09. Lo mismo pasa con el mes cuando naciste entre el mes 1 al 9.

La homoclave es otra cosa pero prometo regresar con el calculo algun otro dia.

_Neo_

Saludos y GRACIAS cesar_nava por sacarnos de la ignorancia

Myakire 22/07/2005 11:23

Encontré este otro, pero esta en FOX

Código:

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_fecnac),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


RootK 22/07/2005 11:43

Buena la info Myakire :arriba:

Les voy a echar un ojo y despues pasar lo que pusiste en T/SQL lo pasaré a otro lenguaje e irlo adaptando a los demas..

Lo que mas me interesaba era el digito verificador.. pero quedaremos en espera de como se obtiene la homoclave.. :pensando:

webbeginner 01/08/2005 18:18

Yo ya escribi en 2 ocasiones a la Secretaria de Hacienda y no me hacen caso, y como bien dice cesar_nava de que se puede se puede, pero al parecer nadie quiere proporcionar ese algoritmo. Esos programas que posteo cesar ya los habia visto y como seguramente lo notaron, si obtiene correctamente la homoclave.

Sigamos buscando, y si alguien logra obtenerlo, por favor publiquelo en el foro

Myakire 02/08/2005 08:46

Caray webbeginner ...... ¿que acaso no te fijaste que hay posteados un procedimiento almacenado y un modulo en fox que ya lo hacen?

MaxExtreme 03/08/2005 17:47

Esto es como en España la letra que acompaña de siempre al número de identificación real. No sirve para nada, es obtenida desde el número y el algoritmo es conocido abiertamente.

webbeginner 03/08/2005 22:49

Cita:

Iniciado por Myakire
Caray webbeginner ...... ¿que acaso no te fijaste que hay posteados un procedimiento almacenado y un modulo en fox que ya lo hacen?


:borracho: lo siento, no me di cuenta.


Desconozco el uso de FOx, pero me voy a poner manos a la obra. Dado esto, quisiera preguntar sobre el codigo posteado ¿Ya calcula la homoclave???

Gracias
:arriba:


.

Myakire 04/08/2005 07:49

Cita:

Dado esto, quisiera preguntar sobre el codigo posteado ¿Ya calcula la homoclave???
Claro, implementa por ejemplo el SP y pruébalo. Luego analiza la rutina de la homoclave.

webbeginner 07/08/2005 01:03

Gracias por responder Myakire.

;-)

robertocorona 25/06/2006 13:00

Calcular Digitoverificador RFC - CURP
 
he logrado calcular el RFC con digito verificador
y he logrado calcular la CURP pero NO logro calcular el digito verificador, ¿alguien tendra un ejemplo de codigo en visual basic para calcularlo?

Torheit 20/07/2006 12:49

Codigo VB para obtener RFC
 
Hola a todos:

Me permiti pasar parte del store procedure que posteo Myakire a codigo VB.
No he podido pasarlo todo por falta de tiempo, pero esta parte es funcional y obtiene el RFC sin homoclave. Espero sirva.

Código:

Function calcular_rfc(NOMBRES_AUX As String, _
                      APATERNO_AUX As String, _
                      AMATERNO_AUX As String, _
                      FECHANACIMIENTO As Date) As String

Dim NOMBRES As String
Dim APATERNO As String
Dim AMATERNO As String
Dim T_NOMTOT As String
Dim NOMBRE1 As String 'PRIMER NOMBRE
Dim NOMBRE2 As String 'DEMAS NOMBRES
Dim NOMBRES_LONGITUD As Integer 'LONGITUD DE TODOS NOMBRES
Dim NOMBRE1_LONGITUD As Integer 'LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
Dim APATERNO1 As String 'PRIMER NOMBRE
Dim APATERNO2 As String 'DEMAS NOMBRES
Dim APATERNO_LONGITUD As Integer 'LONGITUD DE TODOS NOMBRES
Dim APATERNO1_LONGITUD As Integer 'LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
Dim AMATERNO1 As String 'PRIMER NOMBRE
Dim AMATERNO2 As String 'DEMAS NOMBRES
Dim AMATERNO_LONGITUD As Integer 'LONGITUD DE TODOS NOMBRES
Dim AMATERNO1_LONGITUD As Integer 'LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
Dim VARLOOPS As Integer 'VARIABLE PARA LOS LOOPS, SE INICIALIZA AL INICIR UN LOOP
Dim RFC As String
Dim T_NOMNUM As String 'Nombre numerico
Dim T_SUMA As Integer
Dim T_DIVID As Integer ' Dividendo
Dim T_MOD As Integer ' MOD de la division
Dim T_HOMOCLV As String ' Homoclave
Dim T_NUMERO As Integer ' Numero ASC asignado a un caracter
Dim T_PARCIAL As Integer ' Acumulado de la suma de los caracteres del RFC
Dim strAuxBusqueda00 As String  ' se agrega variable para poder quitar los nombre de JOSE, MARIA,MA,etc.
Dim strAuxBusqueda01 As String  ' se agrega variable para poder quitar los nombre de JOSE, MARIA,MA,etc.
Dim strAuxBusqueda02 As String  ' se agrega variable para poder buscar A,E,I,O,U
Dim strChar00 As String ' se agrega variable para manejar substrings
Dim strChar01 As String ' se agrega variable para manejar substrings

'INICIALZA VARIABLES
NOMBRES = UCase(LTrim(RTrim(NOMBRES_AUX)))
APATERNO = UCase(LTrim(RTrim(APATERNO_AUX)))
AMATERNO = UCase(LTrim(RTrim(AMATERNO_AUX)))
T_NOMTOT = APATERNO + " " + AMATERNO + " " + NOMBRES
strAuxBusqueda00 = "JOSE,MARIA,MA.,MA,DE,LA,LAS,MC,VON,DEL,LOS,Y,MAC,VAN"
strAuxBusqueda01 = "DE,LA,LAS,MC,VON,DEL,LOS,Y,MAC,VAN"
strAuxBusqueda02 = "A,E,I,O,U"

'PROCESAR NOMBRES DE PILA
VARLOOPS = 0
While VARLOOPS <> 1
  NOMBRES_LONGITUD = Len(NOMBRES)
  NOMBRE1_LONGITUD = InStr(NOMBRES, " ")

  If NOMBRE1_LONGITUD = 0 Then
    NOMBRE1_LONGITUD = NOMBRES_LONGITUD
  End If

  NOMBRE1 = RTrim(Left$(NOMBRES, NOMBRE1_LONGITUD))
  NOMBRE2 = LTrim(Right$(NOMBRES, NOMBRES_LONGITUD - NOMBRE1_LONGITUD))

  'SE QUINTAN LOS NOMBRES DE JOSE, MARIA,MA,MA.
  'IF NOMBRE1 IN ('JOSE','MARIA','MA.','MA','DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND NOMBRE2 <> ''
  'comparacion original y se cambio por instr
  If InStr(strAuxBusqueda00, NOMBRE1) <> 0 And Len(NOMBRE2) <> 0 Then
    NOMBRES = NOMBRE2
  Else
    VARLOOPS = 1
  End If
Wend

'PROCESAMOS APELLIDOS, PATERNO EN UN LOOP
VARLOOPS = 0
While VARLOOPS <> 1
  APATERNO_LONGITUD = Len(APATERNO)
  APATERNO1_LONGITUD = InStr(APATERNO, " ")

  If PATERNO1_LONGITUD = 0 Then
    APATERNO1_LONGITUD = APATERNO_LONGITUD
  End If

  APATERNO1 = RTrim(Left$(APATERNO, APATERNO1_LONGITUD))
  APATERNO2 = LTrim(Right$(APATERNO, APATERNO_LONGITUD - APATERNO1_LONGITUD))

  'SE QUINTAN LOS SUFIJOS
  'IF APATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND APATERNO2 <> ''
  If InStr(strAuxBusqueda01, APATERNO1) <> 0 And Len(APATERNO2) <> 0 Then
    APATERNO = APATERNO2
  Else
      VARLOOPS = 1
  End If
Wend

'PROCESAMOS APELLIDOS, MATERNO EN UN LOOP
VARLOOPS = 0
While VARLOOPS <> 1
  AMATERNO_LONGITUD = Len(AMATERNO)
  AMATERNO1_LONGITUD = InStr(AMATERNO, " ")

  If AMATERNO1_LONGITUD = 0 Then
    AMATERNO1_LONGITUD = AMATERNO_LONGITUD
  End If

  AMATERNO1 = RTrim(Left$(AMATERNO, AMATERNO1_LONGITUD))
  AMATERNO2 = LTrim(Right$(AMATERNO, AMATERNO_LONGITUD - AMATERNO1_LONGITUD))

  'SE QUINTAN LOS SUFIJOS
  'IF AMATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND AMATERNO2 <> ''
  If InStr(strAuxBusqueda01, AMATERNO1) <> 0 And Len(AMATERNO2) <> 0 Then
    AMATERNO = AMATERNO2
  Else
      VARLOOPS = 1
  End If
Wend

'SE OBTIENE DEL PRIMER APELLIDO LA PRIMER LETRA Y LA PRIMER VOCAL INTERNA
RFC = Left$(APATERNO1, 1)
APATERNO1_LONGITUD = Len(APATERNO1)
VARLOOPS = 1 'EMPIEZA EN UNO POR LA PRIMERA LETRA SE LA VA A SALTAR

While APATERNO1_LONGITUD > VARLOOPS
  VARLOOPS = VARLOOPS + 1

  strChar00 = Mid$(APATERNO1, VARLOOPS, 1)
  'IF SUBSTRING(APATERNO1,VARLOOPS,1) IN ('A','E','I','O','U')
  If InStr(strAuxBusqueda02, strChar00) > 0 Then
    RFC = RTrim(RFC) + strChar00
    VARLOOPS = APATERNO1_LONGITUD
  End If
Wend

'SE OBTIENE LA PRIMER LETRA DEL APELLIDO MATERNO SI NO TIENE APELLIDO MATERNO SE PONE UNA X
'DICE QUE SI NO TIENE APELLIDO MATERNO LE PONGAS LA PRIMER LETRA DEL APELLIDO PATERNO EN EL RFX

If Len(AMATERNO1) = 0 Then
  RFC = RTrim(RFC) + Mid$(APATERNO1, 1, 1)
Else
  RFC = RTrim(RFC) + Mid$(AMATERNO1, 1, 1)
End If

'SE LE AGREGA LA PRIMER LETRA DEL NOMBRE
RFC = RTrim(RFC) + Mid$(NOMBRE1, 1, 1)

'CHECAS QUE NO SEA UNA PALARA INCONVENIENTE
'
'IF EXISTS ( SELECT INC_PALINC FROM NINCO WHERE INC_PALINC = RFC )
'BEGIN
'SELECT RFC = LTRIM(RTRIM (SUBSTRING (RFC , 1 , 3))) + 'X'
'END

'SE LE AGREGA LA FECHA DE NACIMIENTO

'SET RFC = RTRIM(RFC) + CONVERT(CHAR,FECHANACIMIENTO,12)
RFC = RTrim(RFC) + Format(FECHANACIMIENTO, "yymmdd")

calcular_rfc = RFC

End Function


hyadus 03/08/2006 12:34

Me tomé la libertad de "convertir" el código para calcular el RFC a C#, espero que alguien le sea útil. Saludos.

------------------------------------------------------------

Código:

/// <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);
        }
}


RootK 04/08/2006 13:34

hyadus, copie y pegúe tu código tal cual pero en ésta línea:

//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);

me marca error, inclusive usé la fecha que tienes de ejemplo (680825)

si tengo tiempo le echaré un ojo a tu code..

Salu2

wolwery 11/08/2006 13:17

Java
 
[QUOTE=hyadus;1648019]Me tomé la libertad de "convertir" el código para calcular el RFC a C#, espero que alguien le sea útil. Saludos.

------------------------------------------------------------
Tu codigo no lo tendras en Java, de casualidad

blackwind 12/08/2006 19:24

Cita:

Iniciado por wolwery (Mensaje 1657754)
------------------------------------------------------------
Tu codigo no lo tendras en Java, de casualidad

si sabes java, y lees el codigo en c#, notaras que el 90% del codigo es compatible con java (si no es que todo).....

josejuanpache 10/11/2006 10:56

Cita:

Iniciado por robertocorona (Mensaje 1599936)
he logrado calcular el RFC con digito verificador
y he logrado calcular la CURP pero NO logro calcular el digito verificador, ¿alguien tendra un ejemplo de codigo en visual basic para calcularlo?

un favor opasame el codigo de como calcular la curp en delphi 6

demiurgo_daemon 14/12/2006 20:09

Personas fisicas bien; personas morales?
 
usé el código escrito en c# y funciona bien. tengo una pregunta: ¿qué cambios debo hacer al algoritmo para que funcione con personas morales?

gracias


La zona horaria es GMT -6. Ahora son las 14:33.

Desarrollado por vBulletin® Versión 3.8.7
Derechos de Autor ©2000 - 2025, Jelsoft Enterprises Ltd.