Mi primer aportación al foro: Una clase mejorada para generar el RFC de Hacienda en México, a partir de la que me encontré en otro foro (http://ba-k.com/showpost.php?p=4816443&postcount=13).
Código PHP:
<?php
function rfcset($a, $b) {
if(!$a) return $b; else return $a;
}
class RFC {
var $nombre, $apellidoPaterno, $apellidoMaterno, $fecha, $rfc;
function RFC($nombre, $apellidoPaterno, $apellidoMaterno, $fecha, $soloHomoclave = false) {
$this->nombre = strtoupper(trim($nombre));
$this->apellidoPaterno = $this->QuitarArticulos(strtoupper(trim($apellidoPaterno)));
$this->apellidoMaterno = $this->QuitarArticulos(strtoupper(trim($apellidoMaterno)));
$this->rfc = substr($this->apellidoPaterno, 0, 1);
for($i = 1; $i < strlen($this->apellidoPaterno); $i++) {
$c = $this->apellidoPaterno[$i];
if($this->EsVocal($c)) {
$this->rfc .= $c;
break;
}
}
$this->rfc .= substr($this->apellidoMaterno, 0, 1) . substr($this->QuitaNombreComun($this->nombre), 0, $this->apellidoMaterno ? 1 : 2);
$this->rfc = $this->QuitaPalabraMala($this->rfc);
$efecha = explode("-", $fecha);
$efecha[0] = substr($efecha[0], 2, 2);
$efecha[1] = str_pad($efecha[1], 2, '0', STR_PAD_LEFT);
$efecha[2] = str_pad($efecha[2], 2, '0', STR_PAD_LEFT);
$this->rfc .= implode("", $efecha);
$homoclave = $this->CalcularHomoclave($this->apellidoPaterno . " " . $this->apellidoMaterno . " " . $this->nombre);
if(!$soloHomoclave) $this->rfc .= $homoclave; else $this->rfc = $homoclave;
}
function EsVocal($letra) {
return in_array(strtoupper($letra), array("A", "E", "I", "O", "U", "Á", "É", "Í", "Ó", "Ú"));
}
function QuitarArticulos($palabra) {
return preg_replace('/\b(DE(L)?|LA(S)?|LOS|Y|A|VON|VAN)\s+/i', '', $palabra);
}
function QuitaNombreComun($palabra) {
return preg_replace('/\b(DE(L)?|LA(S)?|LOS|Y|A|VON|VAN)\s+/i', '', preg_replace('/\b(J(OSE|\.)?|MA(RIA|\.)?)\s+/i', '', $palabra));
}
function QuitaPalabraMala($palabra) {
return in_array($palabra, array("BUEI", "BUEY", "CACA", "CACO", "CAGA", "CAGO", "CAKA", "CAKO", "COGE", "COJA", "KOGE", "KOJO", "KAKA", "KULO", "MAME", "MAMO", "MEAR", "MEAS", "MEON", "MION", "COJE", "COJI", "COJO", "CULO", "FETO", "GUEY", "JOTO", "KACA", "KACO", "KAGA", "KAGO", "MOCO", "MULA", "PEDA", "PEDO", "PENE", "PUTA", "PUTO", "QULO", "RATA", "RUIN")) ? substr_replace($palabra, "X", 3, 1) : $palabra;
}
function CalcularHomoclave($nombreCompleto) {
$nombreEnNumero = "";
$valorSuma = 0;
$tablaRFC1 = array();
$tablaRFC1["&"] = 10; $tablaRFC1["Ñ"] = 10; $tablaRFC1["A"] = 11; $tablaRFC1["B"] = 12; $tablaRFC1["C"] = 13;
$tablaRFC1["D"] = 14; $tablaRFC1["E"] = 15; $tablaRFC1["F"] = 16; $tablaRFC1["G"] = 17; $tablaRFC1["H"] = 18;
$tablaRFC1["I"] = 19; $tablaRFC1["J"] = 21; $tablaRFC1["K"] = 22; $tablaRFC1["L"] = 23; $tablaRFC1["M"] = 24;
$tablaRFC1["N"] = 25; $tablaRFC1["O"] = 26; $tablaRFC1["P"] = 27; $tablaRFC1["Q"] = 28; $tablaRFC1["R"] = 29;
$tablaRFC1["S"] = 32; $tablaRFC1["T"] = 33; $tablaRFC1["U"] = 34; $tablaRFC1["V"] = 35; $tablaRFC1["W"] = 36;
$tablaRFC1["X"] = 37; $tablaRFC1["Y"] = 38; $tablaRFC1["Z"] = 39; $tablaRFC1["0"] = 0; $tablaRFC1["1"] = 1;
$tablaRFC1["2"] = 2; $tablaRFC1["3"] = 3; $tablaRFC1["4"] = 4; $tablaRFC1["5"] = 5; $tablaRFC1["6"] = 6;
$tablaRFC1["7"] = 7; $tablaRFC1["8"] = 8; $tablaRFC1["9"] = 9;
$tablaRFC2 = array();
$tablaRFC2[0] = "1"; $tablaRFC2[1] = "2"; $tablaRFC2[2] = "3"; $tablaRFC2[3] = "4"; $tablaRFC2[4] = "5";
$tablaRFC2[5] = "6"; $tablaRFC2[6] = "7"; $tablaRFC2[7] = "8"; $tablaRFC2[8] = "9"; $tablaRFC2[9] = "A";
$tablaRFC2[10] = "B"; $tablaRFC2[11] = "C"; $tablaRFC2[12] = "D"; $tablaRFC2[13] = "E"; $tablaRFC2[14] = "F";
$tablaRFC2[15] = "G"; $tablaRFC2[16] = "H"; $tablaRFC2[17] = "I"; $tablaRFC2[18] = "J"; $tablaRFC2[19] = "K";
$tablaRFC2[20] = "L"; $tablaRFC2[21] = "M"; $tablaRFC2[22] = "N"; $tablaRFC2[23] = "P"; $tablaRFC2[24] = "Q";
$tablaRFC2[25] = "R"; $tablaRFC2[26] = "S"; $tablaRFC2[27] = "T"; $tablaRFC2[28] = "U"; $tablaRFC2[29] = "V";
$tablaRFC2[30] = "W"; $tablaRFC2[31] = "X"; $tablaRFC2[32] = "Y";
$tablaRFC3 = array();
$tablaRFC3["A"] = 10; $tablaRFC3["B"] = 11; $tablaRFC3["C"] = 12; $tablaRFC3["D"] = 13; $tablaRFC3["E"] = 14;
$tablaRFC3["F"] = 15; $tablaRFC3["G"] = 16; $tablaRFC3["H"] = 17; $tablaRFC3["I"] = 18; $tablaRFC3["J"] = 19;
$tablaRFC3["K"] = 20; $tablaRFC3["L"] = 21; $tablaRFC3["M"] = 22; $tablaRFC3["N"] = 23; $tablaRFC3["O"] = 25;
$tablaRFC3["P"] = 26; $tablaRFC3["Q"] = 27; $tablaRFC3["R"] = 28; $tablaRFC3["S"] = 29; $tablaRFC3["T"] = 30;
$tablaRFC3["U"] = 31; $tablaRFC3["V"] = 32; $tablaRFC3["W"] = 33; $tablaRFC3["X"] = 34; $tablaRFC3["Y"] = 35;
$tablaRFC3["Z"] = 36; $tablaRFC3["0"] = 0; $tablaRFC3["1"] = 1; $tablaRFC3["2"] = 2; $tablaRFC3["3"] = 3;
$tablaRFC3["4"] = 4; $tablaRFC3["5"] = 5; $tablaRFC3["6"] = 6; $tablaRFC3["7"] = 7; $tablaRFC3["8"] = 8;
$tablaRFC3["9"] = 9; $tablaRFC3[""] = 24; $tablaRFC3[" "] = 37;
$nombreEnNumero = "0";
for($i = 0; $i < strlen($nombreCompleto); $i++) {
$c = $nombreCompleto[$i];
$nombreEnNumero .= rfcset($tablaRFC1[$c], "00");
}
for ($i = 0; $i < strlen($nombreEnNumero) - 1; $i++) {
$i2 = $i + 1;
$valorSuma += (($nombreEnNumero[$i] * 10) + $nombreEnNumero[$i2]) * $nombreEnNumero[$i2];
}
$div = 0; $mod = 0;
$div = $valorSuma % 1000;
$mod = $div % 34;
$div = ($div - $mod) / 34;
$hc = "" . rfcset($tablaRFC2[$div], "Z") . rfcset($tablaRFC2[$mod], "Z");
$rfc = $this->rfc . $hc;
$rfcAnumeroSuma = 0;
$sumaParcial = 0;
for($i = 0; $i < strlen($rfc); $i++) {
if($tablaRFC3[$rfc[$i]]) {
$rfcAnumeroSuma = $tablaRFC3[$rfc[$i]];
$sumaParcial += ($rfcAnumeroSuma * (14 - ($i + 1)));
}
}
$moduloVerificador = $sumaParcial % 11;
if($moduloVerificador == 0) $hc .= "0";
else {
$sumaParcial = 11 - $moduloVerificador;
if ($sumaParcial == 10) $hc .= "A"; else $hc .= $sumaParcial;
}
return $hc;
}
}
?>
<?php
/* Agrega una diagonal al principio de este renglón para cancelar el área de comentario
$nombres = "JOSE EDUARDO";
$apellidoPaterno = "CORTES";
$apellidoMaterno = "GODINEZ";
$fecha = "1980-01-01";
$rfc = new RFC ($nombres, $apellidoPaterno, $apellidoMaterno, $fecha); // Agrega 'true' al final para sólo homoclave
echo $rfc->rfc;
/*///*/
?>
Cabe mencionar que he probado con esta clase varios RFCs que inventé y los comparé con los que genera la página de Recaudanet (https://www.recaudanet.gob.mx/recaudanet/rfc.jsp), que considero más confiable que cualquier programa o página que otras personas y/o empresas han hecho, y también probé y comparé con RFCs que ya tenía para los casos en que la persona no tiene apellido materno, pues la página de Recaudanet no calcula el RFC si no tiene todos los datos.
Se agradecen sus comentarios.