-
-
Save joaohcrangel/8bd48bcc40b9db63bef7201143303937 to your computer and use it in GitHub Desktop.
function isValidCPF(value: string) { | |
if (typeof value !== 'string') { | |
return false; | |
} | |
value = value.replace(/[^\d]+/g, ''); | |
if (value.length !== 11 || !!value.match(/(\d)\1{10}/)) { | |
return false; | |
} | |
const values = value.split('').map(el => +el); | |
const rest = (count) => (values.slice(0, count-12).reduce( (soma, el, index) => (soma + el * (count-index)), 0 )*10) % 11 % 10; | |
return rest(10) === values[9] && rest(11) === values[10]; | |
} |
Receita Federal
função disponibilizada pelo próprio site da Receita Federal
Tenho uma sugestão usando paradigma funcional, e um pouco mais reduzido 🤓
function isValidCPF(cpf) {
if (typeof cpf !== 'string') return false
cpf = cpf.replace(/[^\d]+/g, '')
if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false
cpf = cpf.split('')
const validator = cpf
.filter((digit, index, array) => index >= array.length - 2 && digit)
.map( el => +el )
const toValidate = pop => cpf
.filter((digit, index, array) => index < array.length - pop && digit)
.map(el => +el)
const rest = (count, pop) => (toValidate(pop)
.reduce((soma, el, i) => soma + el * (count - i), 0) * 10) % 11 % 10
return !(rest(10,2) !== validator[0] || rest(11,1) !== validator[1])
}
Pra quem quer entender:
function isValidCPF(cpf) {
// Validar se é String
if (typeof cpf !== 'string') return false
// Tirar formatação
cpf = cpf.replace(/[^\d]+/g, '')
// Validar se tem tamanho 11 ou se é uma sequência de digitos repetidos
if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false
// String para Array
cpf = cpf.split('')
const validator = cpf
// Pegar os últimos 2 digitos de validação
.filter((digit, index, array) => index >= array.length - 2 && digit)
// Transformar digitos em números
.map( el => +el )
const toValidate = pop => cpf
// Pegar Array de items para validar
.filter((digit, index, array) => index < array.length - pop && digit)
// Transformar digitos em números
.map(el => +el)
const rest = (count, pop) => (toValidate(pop)
// Calcular Soma dos digitos e multiplicar por 10
.reduce((soma, el, i) => soma + el * (count - i), 0) * 10)
// Pegar o resto por 11
% 11
// transformar de 10 para 0
% 10
return !(rest(10,2) !== validator[0] || rest(11,1) !== validator[1])
}
Esta função já retorna um booleano (verdadeiro ou falso), logo não precisa comparar dentro de um condicional (if)... só chamar a função!
if ( isValidCPF(cpf) ) // só executa se for cpf válido
if ( !isValidCPF(cpf) ) // só executa se não for um cpf válido
chama essa função no input ou no button?
Tanto faz.
<form onsubmit="isValidCPF()"> CPF: <input id="cpf" type="text"> <input type="submit"> </form>
E na função:
function isValidCPF() { let cpf = document.getElementById("cpf").value; // Resto do código...
chama essa função no input ou no button?
Tanto faz.
<form onsubmit="isValidCPF()"> CPF: <input id="cpf" type="text"> <input type="submit"> </form>
E na função:
function isValidCPF() { let cpf = document.getElementById("cpf").value; // Resto do código...
Aqui não deu certo, estou tentando disparar um alerta com o resulado, está correto?
if (isValidCPF(cpf) == 0) {
window.alert ("Valido")
} else {
window.alert ("Invalido")
}
//obrigado @jaronwanderley por disponibilizar a função de validação de cpf vou usar ela
//caso alguem precise no disparo do alerta que não deu certo é só colocar assim.
// onde o retorno true da funcao significa que o CPF foi validado
//meu instagram: @elanodahora
if (isValidCPF(cpf) == true){
window.alert ("Valido")
} else {
window.alert ("invalido")
}
@elanodahora eu quem agradeço a referência.
mas não precisa comparar com true
if ( isValidCPF(cpf) )
já funciona!
eu usaria desta maneira...
if ( !isValidCPF(cpf) ) { window.alert ("Invalido") // mais algo pra fazer } window.alert ("Válido") // mais algo pra fazer
assim você trata a excessão primeiro e o resto é o caso de sucesso!
Tenho uma sugestão usando paradigma funcional, e um pouco mais reduzido 🤓
function isValidCPF(cpf) { if (typeof cpf !== 'string') return false cpf = cpf.replace(/[^\d]+/g, '') if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false cpf = cpf.split('') const validator = cpf .filter((digit, index, array) => index >= array.length - 2 && digit) .map( el => +el ) const toValidate = pop => cpf .filter((digit, index, array) => index < array.length - pop && digit) .map(el => +el) const rest = (count, pop) => (toValidate(pop) .reduce((soma, el, i) => soma + el * (count - i), 0) * 10) % 11 % 10 return !(rest(10,2) !== validator[0] || rest(11,1) !== validator[1]) }
Ainda mais simplificado kkk
function isValidCPF(cpf) {
if (typeof cpf !== 'string') return false
cpf = cpf.replace(/[^\d]+/g, '')
if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false
cpf = cpf.split('').map(el => +el)
const rest = (count) => (cpf.slice(0, count-12)
.reduce( (soma, el, index) => (soma + el * (count-index)), 0 )*10) % 11 % 10
return rest(10) === cpf[9] && rest(11) === cpf[10]
}
Obrigado pelas contribuições!
Aproveitei a função bem resumida do @bestknighter a apenas ajustei para usar com TypeScript.
Apliquei no meu código e ficou perfeito. Muito obrigado!
TypeScript + Zod:
cpf: z.string().refine((cpf: string) => {
if (typeof cpf !== "string") return false;
cpf = cpf.replace(/[^\d]+/g, "");
if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false;
const cpfDigits = cpf.split("").map((el) => +el);
const rest = (count: number): number => {
return (((cpfDigits.slice(0, count - 12).reduce((soma, el, index) => soma + el * (count - index), 0) * 10) % 11) % 10);
};
return rest(10) === cpfDigits[9] && rest(11) === cpfDigits[10];
}, "Digite um cpf válido."),
TypeScript + Zod:
cpf: z.string().refine((cpf: string) => { if (typeof cpf !== "string") return false; cpf = cpf.replace(/[^\d]+/g, ""); if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false; const cpfDigits = cpf.split("").map((el) => +el); const rest = (count: number): number => { return (((cpfDigits.slice(0, count - 12).reduce((soma, el, index) => soma + el * (count - index), 0) * 10) % 11) % 10); }; return rest(10) === cpfDigits[9] && rest(11) === cpfDigits[10]; }, "Digite um cpf válido."),
Obrigado! Funcionou que é uma beleza!
Mano, essa galera do JS tem problema, nao é possível... O cara posta uma função para validar CPF em TYPESCRIPT aí os maluco vem um querendo ser um "melhor" que o outro e começam a dar variações de funções do nada, com problema de lógica, sem typescript, focando em fazer um código todo esmagado, quase impossível de ler e dar manutenção, usando framework que ele tirou da cabeça e ninguém pediu... Teve até maluco com função PHP nessa loucura... Gente, qual o problema de vocês?
Se for comentar, comente algo útil! Comente algo que MELHORE a função do cara REFATORANDO a versão dele. Não faz sentido nenhum postar OUTRA completamente diferente... Para isso, crie seu próprio gist...
Cada uma... Já fiquei irritado aqui, ta louco...
Entrei aqui pra pegar a função do cara, um monte de gente comentou, mas no final das contas vou ter que pegar a original do cara pq é a única descente aqui usando Typescript, ou seja, um monte de comentário inútil.... 🤦
(não que esse meu aqui não seja também inútil)
Mano, essa galera do JS tem problema, nao é possível... O cara posta uma função para validar CPF em TYPESCRIPT aí os maluco vem um querendo ser um "melhor" que o outro e começam a dar variações de funções do nada, com problema de lógica, sem typescript, focando em fazer um código todo esmagado, quase impossível de ler e dar manutenção, usando framework que ele tirou da cabeça e ninguém pediu... Teve até maluco com função PHP nessa loucura... Gente, qual o problema de vocês?
Se for comentar, comente algo útil! Comente algo que MELHORE a função do cara REFATORANDO a versão dele. Não faz sentido nenhum postar OUTRA completamente diferente... Para isso, crie seu próprio gist...
Cada uma... Já fiquei irritado aqui, ta louco...
Entrei aqui pra pegar a função do cara, um monte de gente comentou, mas no final das contas vou ter que pegar a original do cara pq é a única descente aqui usando Typescript, ou seja, um monte de comentário inútil.... 🤦 (não que esse meu aqui não seja também inútil)
Irmão, tá tudo bem? Vc teve um dia ruim ou algo assim? Dá uma respirada, toma uma água... Nem o dono do Gist se incomodou com isso. Ele até agradeceu.
Ter a mesma função implementada em várias linguagens é positivo para a comunidade open source.
E se o problema for dificuldade para entender o código para dar manutenção (ou portar para outras linguagens, pq o funcionamento está matematicamente correto), segue uma versão comentada:
function isValidCPF(cpf) {
// Se não for string, o CPF é inválido
if (typeof cpf !== 'string') return false
// Remove todos os caracteres que não sejam números
cpf = cpf.replace(/[^\d]+/g, '')
// Se o CPF não tem 11 dígitos ou todos os dígitos são repetidos, o CPF é inválido
if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false
// Transforma de string para number[] com cada dígito sendo um número no array
cpf = cpf.split('').map(el => +el)
// Cria uma função interna que calcula o dígito verificador do CPF atual:
const rest = (count) =>
// Pega os primeiros count dígitos
(cpf.slice(0, count-12)
// e calcula o dígito verificador de acordo com a fórmula da Receita Federal
.reduce( (soma, el, index) => (soma + el * (count-index)), 0 ) * 10 ) % 11 % 10
// O CPF é válido se, e somente se, os dígitos verificadores estão corretos
return rest(10) === cpf[9] && rest(11) === cpf[10]
}
Essas refatorações ajudam o código a ficar menor e mais performático. Além de reduzir pontos de falha. E eu particularmente acho essa versão final mais fácil de se manter do que a inicial. Talvez tudo isso não seja necessário para algumas pessoas, mas para algumas outras seja necessário sim. Fornecer um código curto e eficiente logo de cara é bem melhor do que um gigante e lento.
Se o que vc queria era uma explicação de como o código funciona, era só pedir 😜
Aí, olha só... Os cara nao param velho... Essa galera do JS tem problema, nao é possível ahskkhaskhakskahs
Gente, como q eu uso o documento.elemente by ID com alguma variavel do typebot.
Mano, essa galera do JS tem problema, nao é possível... O cara posta uma função para validar CPF em TYPESCRIPT aí os maluco vem um querendo ser um "melhor" que o outro e começam a dar variações de funções do nada, com problema de lógica, sem typescript, focando em fazer um código todo esmagado, quase impossível de ler e dar manutenção, usando framework que ele tirou da cabeça e ninguém pediu... Teve até maluco com função PHP nessa loucura... Gente, qual o problema de vocês?
Se for comentar, comente algo útil! Comente algo que MELHORE a função do cara REFATORANDO a versão dele. Não faz sentido nenhum postar OUTRA completamente diferente... Para isso, crie seu próprio gist...
Cada uma... Já fiquei irritado aqui, ta louco...
Entrei aqui pra pegar a função do cara, um monte de gente comentou, mas no final das contas vou ter que pegar a original do cara pq é a única descente aqui usando Typescript, ou seja, um monte de comentário inútil.... 🤦 (não que esse meu aqui não seja também inútil)
Não vejo problema nenhum nas pessoas querem melhor um código existente. Isso é uma das qualidades mais importantes de um bom programador. Eu até prefiro que um código que estou prestes a roubar tenha sido validado e melhorado por vários programadores.
Meu problema é que da pra "sentir" em alguns textos que tem gente querendo puxar ego sem ter feito grande coisa, esse tipo de pessoa vai atrapalhar dms o leitor, fazendo ele perder tempo pra krl lendo o quão foda e dificil é seja la a merda que ela fez.
Não me entendam mal, eu iria gostar se algum maluco tivesse postado um validador de cep extremamente eficiente aqui, mostrando o quão melhor o código dele é (usando benchmarks), mas nesse ponto é melhor fazer uma rinha de validador de CPF.
Com isso dito, os posts desse gist estão bem amigaveis. Se vc achou os comentarios desse gist ruins, acho melhor passar longe do stackOverflow pra copiar código.
btw vc não precisava ler os comentários, o cara que postou esse gist fez várias revisões de acordo com a galera do chat.
Você está certíssimo! haha
não queria comentar, mas hoje eu tô no humor pra falar, se não gostou faz do seu seu jeito.
Você como programador deveria saber o que é melhor pra sua aplicação (se não tem essa capacidade, seja humilde e pergunte o porque das coisas)... ter alternativas não prejudica em nada a comunidade
Tem gente que parece que quer biscoito 🍪
Precisei dessa função novamente em outro projeto. Só que nele eu tbm precisava da função que gerava o dígito verificador em outros lugares do código. Lá eu transformei ela num método funcional puro e extraí para o mesmo módulo. Apliquei a mesma mudança aqui mas mantive dentro da função para não poluir o escopo.
function isValidCPF(value: string) {
// Se não for string, o CPF é inválido
if (typeof value !== 'string') {
return false;
}
// Remove todos os caracteres que não sejam números
value = value.replace(/[^\d]+/g, '');
// Se o CPF não tem 11 dígitos ou todos os dígitos são repetidos, o CPF é inválido
if (value.length !== 11 || !!value.match(/(\d)\1{10}/)) {
return false;
}
// Transforma de string para number[] com cada dígito sendo um número no array
const digits = value.split('').map(el => +el);
// Função que calcula o dígito verificador de acordo com a fórmula da Receita Federal
function getVerifyingDigit(arr: number[]) {
const reduced = arr.reduce( (sum, digit, index)=>(sum + digit * (arr.length - index + 1)), 0 );
return (reduced * 10) % 11 % 10;
}
// O CPF é válido se, e somente se, os dígitos verificadores estão corretos
return getVerifyingDigit(digits.slice(0, 9)) === digits[9]
&& getVerifyingDigit(digits.slice(0, 10)) === digits[10];
}
Para este if:
Eu faria com o seguinte regex: /^(?:(\d)\1{10})$|(\D)|^(\d{12,})$|^(\d{0,10})$/g
Abaixo um exemplo: