Stack Overflow en español Asked by Mariano on December 4, 2021
Pregunta: ¿Cómo puedo verificar que el formato de una CURP mexicana es válido?
¿Qué es la CURP?
La Clave Única de Registro de Población (CURP) es un código alfanumérico único de identidad de 18 caracteres utilizado para identificar oficialmente tanto a residentes como a ciudadanos mexicanos, expedido por el RENAPO.
La misma, se forma a partir de las letras de los nombres y apellidos, la fecha y la entidad federativa de nacimiento, y el sexo. Además, el caracter 17 es para evitar duplicados, y el último caracter es un dígito que se utiliza como detector-corrector de errores. La sintaxis está detallada en el Instructivo Normativo para la Asignación de la Clave Única de Registro de Población ?.
Contexto: Sólo me interesa validar que una clave podría ser válida. No me interesa en este punto ver si esa CURP existe o no.
Hasta ahora, sólo estoy verificando que sean 18 caracteres alfanuméricos con el regex:
/^[A-Zd]{18}$/
pero me interesa también considerar que los caracteres sean válidos, y que el dígito verificador coincida.
Puedes usar la libreria curp que está en NPM
npm install --save curp
Si no usas NPM agregarlo con bundle así.
<script src="https://bundle.run/curp"></script>
Ejemplo funcional:
var validarCurp = document.getElementById("validarCurp");
var validarBoton = document.getElementById("validarBoton");
validarBoton.addEventListener("click", function(evt) {
evt.preventDefault();
if(curp.validar(validarCurp.value)){
alert('Es valido ')
}else{
alert('No es valido')
}
});
<script src="https://bundle.run/curp"></script>
<h2 id="valida">Validar CURP</h2>
<p><strong>CURP:</strong>
<input id="validarCurp" type="text" /></p>
<p><input id="validarBoton" type="button" value="Validar" /></p>
Una alternativa más, sin utilizar javascript, validando solo el formato con la propiedad pattern
, tiene el detalle que no podemos revisar el dígito verificador.
<form>
<label for="curp">CURP:</label>
<input id="curp"
type="text"
required="true"
placeholder="Ingrese su CURP"
pattern="([A-Z]{4}([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[HM](AS|BC|BS|CC|CL|CM|CS|CH|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)[A-Z]{3}[0-9A-Z]d)"
/>
<button>Guardar</button>
</form >
Answered by Israel Perales on December 4, 2021
Muchas gracias. Esto me ayudó a crear un validador para PHP, dejo el código por si a alguien le sirve.
function is_curp( $string = '' ){
// By @JorhelR
// TRANSFORMARMOS EN STRING EN MAYÚSCULAS RESPETANDO LAS Ñ PARA EVITAR ERRORES
$string = mb_strtoupper($string, "UTF-8");
// EL REGEX POR @MARIANO
$pattern = "/^([A-Z][AEIOUX][A-Z]{2}d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]d|3[01])[HM](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Zd])(d)$/";
$validate = preg_match($pattern, $string, $match);
if( $validate === false ){
// SI EL STRING NO CUMPLE CON EL PATRÓN REQUERIDO RETORNA FALSE
return false;
}
// ASIGNAMOS VALOR DE 0 A 36 DIVIDIENDO EL STRING EN UN ARRAY
$ind = preg_split( '//u', '0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ', null, PREG_SPLIT_NO_EMPTY );
// REVERTIMOS EL CURP Y LE COLOCAMOS UN DÍGITO EXTRA PARA QUE EL VALOR DEL PRIMER CARACTER SEA 0 Y EL DEL PRIMER DIGITO DE LA CURP (INVERSA) SEA 1
$vals = str_split( strrev( $match[0]."?" ) );
// ELIMINAMOS EL CARACTER ADICIONAL Y EL PRIMER DIGITO DE LA CURP (INVERSA)
unset( $vals[0] );
unset( $vals[1] );
$tempSum = 0;
foreach( $vals as $v => $d ){
// SE BUSCA EL DÍGITO DE LA CURP EN EL INDICE DE LETRAS Y SU CLAVE(VALOR) SE MULTIPLICA POR LA CLAVE(VALOR) DEL DÍGITO. TODO ESTO SE SUMA EN $tempSum
$tempSum = (array_search( $d, $ind ) * $v)+$tempSum;
}
// ESTO ES DE @MARIANO NO SUPE QUE ERA
$digit = 10 - $tempSum % 10;
// SI EL DIGITO CALCULADO ES 10 ENTONCES SE REASIGNA A 0
$digit = $digit == 10 ? 0 : $digit;
// SI EL DIGITO COINCIDE CON EL ÚLTIMO DÍGITO DE LA CURP RETORNA TRUE, DE LO CONTRARIO FALSE
return $match[2] == $digit;
}
Answered by Jorhel Reyes on December 4, 2021
Una API REST para validar CURP y obtener información básica de la persona. La API es Gratis (peticiones ilimitadas), Rápida (latencia de 200 ms en promedio) y Estandarizada de acuerdo a ISO. Más información usando Postman
Ejemplo de petición:
GET https://domain.com/api/curp/CAHF620818HMNLNL09?apiKey=bpT32rai
Ejemplo de respuesta exitosa:
{
"curp": "CAHF620818HMNLNL09",
"fatherName": "CALDERON",
"motherName": "HINOJOSA",
"name": "FELIPE DE JESUS",
"gender": "1",
"birthday": "1962-01-01T00:08:00.000Z",
"birthState": "MX-MIC"
}
Answered by Carlos Eduardo Sanchez Torres on December 4, 2021
Puedes validar una CURP y la información de la persona usando este API https://rapidapi.com/acrogenesis/api/curp-renapo.
Por ejemplo para usarla en php sería así:
<?php
$client = new httpClient;
$request = new httpClientRequest;
$request->setRequestUrl('https://curp-renapo.p.rapidapi.com/v1/curp/CURP_DE_TU_USUARIO');
$request->setRequestMethod('GET');
$request->setHeaders(array(
'x-rapidapi-host' => 'curp-renapo.p.rapidapi.com',
'x-rapidapi-key' => 'api-key'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
Y te regresaría la información de esta forma:
{
"curp":"CURP_DE_TU_USUARIO"
"renapo_valid":true
"paternal_surname":"CALDERON"
"mothers_maiden_name":"HINOJOSA"
"names":"FELIPE DE JESUS"
"sex":"HOMBRE"
"birthdate":"18/08/1962"
"nationality":"MEXICO"
"entity_birth":"MN"
"probation_document":"ACTA DE NACIMIENTO"
"probation_document_data":{
"Entidad":"16"
"Municipio":"053"
"Año":"1963"
"Número de acta":"00145"
}
"rfc":"RFC_DE_TU_USUARIO"
"sat_valid":true
}
Answered by acrogenesis on December 4, 2021
Según un documento emitido por el SAT, mencionan en la página 3 el siguiente patrón de REGEX, el cual no válida el contenido, sino sólo el formato de la cadena de texto:
[A-Z][A,E,I,O,U,X][A-Z]{2}[0-9]{2}[0-1][0-9][0-3][0-9][M,H][AZ]{2}[B,C,D,F,G,H,J,K,L,M,N,Ñ,P,Q,R,S,T,V,W,X,Y,Z]{3}[0-9,AZ][0-9]
No obstante, es incorrecto en la penúltima parte [0-9,AZ]
, la cual debería estar así [0-9,A-Z]
A nivel código (Java), podría quedar algo así su validación en una clase de Utilería:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Utils {
public final static String REGEX_CURP =
"[A-Z][A,E,I,O,U,X][A-Z]{2}[0-9]{2}[0-1][0-9][0-3][0-9][M,H][A-Z]{2}[B,C,D,F,G,H,J,K,L,M,N,Ñ,P,Q,R,S,T,V,W,X,Y,Z]{3}[0-9,A-Z][0-9]";
public static boolean validarCurp(String textoCurp){
boolean curpValido = false;
Pattern pattern = Pattern.compile(REGEX_CURP;
Matcher matcher = pattern.matcher(textoCurp);
curpValido = matcher.find();
matcher = null;
pattern = null;
return curpValido;
}
}
Answered by Nekio on December 4, 2021
Un poco tarde mi respuesta, pero hace tiempo hice este método para validar los RFC, tanto para personas físicas como personas morales. Los regex los saqué del sitio oficial del SAT para validar RFC. Espero a alguien le sirva. La función está hecha en JS
function validateRFC(rfc) {
var patternPM = "^(([A-ZÑ&]{3})([0-9]{2})([0][13578]|[1][02])(([0][1-9]|[12][\d])|[3][01])([A-Z0-9]{3}))|" +
"(([A-ZÑ&]{3})([0-9]{2})([0][13456789]|[1][012])(([0][1-9]|[12][\d])|[3][0])([A-Z0-9]{3}))|" +
"(([A-ZÑ&]{3})([02468][048]|[13579][26])[0][2]([0][1-9]|[12][\d])([A-Z0-9]{3}))|" +
"(([A-ZÑ&]{3})([0-9]{2})[0][2]([0][1-9]|[1][0-9]|[2][0-8])([A-Z0-9]{3}))$";
var patternPF = "^(([A-ZÑ&]{4})([0-9]{2})([0][13578]|[1][02])(([0][1-9]|[12][\d])|[3][01])([A-Z0-9]{3}))|" +
"(([A-ZÑ&]{4})([0-9]{2})([0][13456789]|[1][012])(([0][1-9]|[12][\d])|[3][0])([A-Z0-9]{3}))|" +
"(([A-ZÑ&]{4})([02468][048]|[13579][26])[0][2]([0][1-9]|[12][\d])([A-Z0-9]{3}))|" +
"(([A-ZÑ&]{4})([0-9]{2})[0][2]([0][1-9]|[1][0-9]|[2][0-8])([A-Z0-9]{3}))$";
if (rfc.match(patternPM) || rfc.match(patternPF)) {
return true;
} else {
alert("La estructura de la clave de RFC es incorrecta.");
return false;
}
}
Answered by ArCiGo on December 4, 2021
La siguiente expresión regular verifica:
/^([A-Z][AEIOUX][A-Z]{2}d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]d|3[01])[HM](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Zd])(d)$/
Publico el código en JavaScript para poder correrlo acá, pero estoy seguro de que es muy sencillo de llevar a cualquier otro lenguaje.
//Función para validar una CURP
function curpValida(curp) {
var re = /^([A-Z][AEIOUX][A-Z]{2}d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]d|3[01])[HM](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Zd])(d)$/,
validado = curp.match(re);
if (!validado) //Coincide con el formato general?
return false;
//Validar que coincida el dígito verificador
function digitoVerificador(curp17) {
//Fuente https://consultas.curp.gob.mx/CurpSP/
var diccionario = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ",
lngSuma = 0.0,
lngDigito = 0.0;
for(var i=0; i<17; i++)
lngSuma = lngSuma + diccionario.indexOf(curp17.charAt(i)) * (18 - i);
lngDigito = 10 - lngSuma % 10;
if (lngDigito == 10) return 0;
return lngDigito;
}
if (validado[2] != digitoVerificador(validado[1]))
return false;
return true; //Validado
}
//Handler para el evento cuando cambia el input
//Lleva la CURP a mayúsculas para validarlo
function validarInput(input) {
var curp = input.value.toUpperCase(),
resultado = document.getElementById("resultado"),
valido = "No válido";
if (curpValida(curp)) { // ⬅️ Acá se comprueba
valido = "Válido";
resultado.classList.add("ok");
} else {
resultado.classList.remove("ok");
}
resultado.innerText = "CURP: " + curp + "nFormato: " + valido;
}
#resultado {
background-color: red;
color: white;
font-weight: bold;
}
#resultado.ok {
background-color: green;
}
<label>CURP:
<input type="text" id="curp_input" oninput="validarInput(this)" style="width:100%;" placeholder="Ingrese su CURP">
</label>
<pre id="resultado"></pre>
Tomando en cuenta la estructura con la que se forma una CURP:
[A-Z]
X
).[AEIOUX]
X
si no tuviese).[A-Z]{2}
d{2}
año.(?:0[1-9]|1[0-2])
mes.(?:0[1-9]|[12]d|3[01])
día.[HM]
(?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)
[B-DF-HJ-NP-TV-Z]{3}
[A-Zd]
(d)
Luego de ver si coincide con el regex, comprobamos que el dígito verificador sea válido. Es decir, si coincide con el calculado de los primeros 17 caracteres:
if (validado[2] != digitoVerificador(validado[1]))
Para calcular el digito, primero se suma el valor de cada uno de los 17 caracteres, los cuales tienen un valor de 0 a 36 según este orden (diccionario):
0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ
for(var i=0; i<17; i++)
lngSuma = lngSuma + diccionario.indexOf(curp17.charAt(i)) * (18 - i);
Y se toma el complemento a 10 del último dígito de esta suma (o 0
si da 10).
lngDigito = 10 - lngSuma % 10;
if (lngDigito == 10) return 0;
return lngDigito;
Answered by Mariano on December 4, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP