[{"data":1,"prerenderedAt":2713},["ShallowReactive",2],{"pt-BR-javascript-category-articles":3},[4,498,1333],{"id":5,"title":6,"articleCover":7,"articleCoverEmbed":8,"articleCoverEmbedUploadDate":8,"articleCoverHeight":9,"articleCoverWidth":10,"authorId":11,"body":12,"categoriesIds":487,"description":488,"enAlternateSlug":8,"extension":489,"meta":490,"navigation":353,"path":491,"ptBrAlternateSlug":8,"publishedAt":492,"seo":493,"sitemap":494,"stem":495,"updatedAt":492,"wordCount":496,"__hash__":497},"blog\u002Fblog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api.md","Como consumir uma API no JavaScript com a Fetch API","\u002Fimages\u002Fblog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api.webp",null,720,1280,"thiago-nunes-batista",{"type":13,"value":14,"toc":481},"minimark",[15,27,30,35,44,48,51,307,310,314,317,333,396,400,403,412,415,434,437,440,477],[16,17,18,19,26],"p",{},"A Fetch API é uma interface nativa do JavaScript que permite realizar requisições HTTP sem a necessidade de instalar bibliotecas de código, como por exemplo, a ",[20,21,25],"a",{"href":22,"rel":23},"https:\u002F\u002Faxios-http.com\u002F",[24],"nofollow","biblioteca Axios",".",[16,28,29],{},"Neste artigo você vai aprender a utilizar a Fetch API através de exemplos práticos somente com HTML e JavaScript.",[31,32,34],"h2",{"id":33},"api","API",[16,36,37,38,43],{},"Foi escolhido uma ",[20,39,42],{"href":40,"rel":41},"https:\u002F\u002Frickandmortyapi.com\u002F",[24],"API gratuita"," com a temática do desenho animado \"Ricky and Morty\" que nos permitirá carregar dados de um endpoint real.",[31,45,47],{"id":46},"html","HTML",[16,49,50],{},"Para o exemplo desse artigo, teremos a seguinte estrutura HTML:",[52,53,57],"pre",{"className":54,"code":55,"language":46,"meta":56,"style":56},"language-html shiki shiki-themes dracula","\u003C!DOCTYPE html>\n\u003Chtml lang=\"en\">\n  \u003Chead>\n    \u003Cmeta charset=\"UTF-8\" \u002F>\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \u002F>\n    \u003Ctitle>Como consumir uma API no JavaScript com a Fetch API\u003C\u002Ftitle>\n  \u003C\u002Fhead>\n  \u003Cbody>\n    \u003Cbutton id=\"load-from-api\">Carregar dados\u003C\u002Fbutton>\n    \u003Cbutton id=\"load-all-characters\">Carregar todos os personagens\u003C\u002Fbutton>\n    \u003Cscript src=\".\u002Fapp.js\">\u003C\u002Fscript>\n  \u003C\u002Fbody>\n\u003C\u002Fhtml>\n","",[58,59,60,80,106,117,141,174,189,199,209,236,261,288,297],"code",{"__ignoreMap":56},[61,62,65,69,73,77],"span",{"class":63,"line":64},"line",1,[61,66,68],{"class":67},"sCdxs","\u003C!",[61,70,72],{"class":71},"s0Tla","DOCTYPE",[61,74,76],{"class":75},"sY_PY"," html",[61,78,79],{"class":67},">\n",[61,81,83,86,88,91,94,98,102,104],{"class":63,"line":82},2,[61,84,85],{"class":67},"\u003C",[61,87,46],{"class":71},[61,89,90],{"class":75}," lang",[61,92,93],{"class":71},"=",[61,95,97],{"class":96},"seVfx","\"",[61,99,101],{"class":100},"s-mGx","en",[61,103,97],{"class":96},[61,105,79],{"class":67},[61,107,109,112,115],{"class":63,"line":108},3,[61,110,111],{"class":67},"  \u003C",[61,113,114],{"class":71},"head",[61,116,79],{"class":67},[61,118,120,123,126,129,131,133,136,138],{"class":63,"line":119},4,[61,121,122],{"class":67},"    \u003C",[61,124,125],{"class":71},"meta",[61,127,128],{"class":75}," charset",[61,130,93],{"class":71},[61,132,97],{"class":96},[61,134,135],{"class":100},"UTF-8",[61,137,97],{"class":96},[61,139,140],{"class":67}," \u002F>\n",[61,142,144,146,148,151,153,155,158,160,163,165,167,170,172],{"class":63,"line":143},5,[61,145,122],{"class":67},[61,147,125],{"class":71},[61,149,150],{"class":75}," name",[61,152,93],{"class":71},[61,154,97],{"class":96},[61,156,157],{"class":100},"viewport",[61,159,97],{"class":96},[61,161,162],{"class":75}," content",[61,164,93],{"class":71},[61,166,97],{"class":96},[61,168,169],{"class":100},"width=device-width, initial-scale=1.0",[61,171,97],{"class":96},[61,173,140],{"class":67},[61,175,177,179,182,185,187],{"class":63,"line":176},6,[61,178,122],{"class":67},[61,180,181],{"class":71},"title",[61,183,184],{"class":67},">Como consumir uma API no JavaScript com a Fetch API\u003C\u002F",[61,186,181],{"class":71},[61,188,79],{"class":67},[61,190,192,195,197],{"class":63,"line":191},7,[61,193,194],{"class":67},"  \u003C\u002F",[61,196,114],{"class":71},[61,198,79],{"class":67},[61,200,202,204,207],{"class":63,"line":201},8,[61,203,111],{"class":67},[61,205,206],{"class":71},"body",[61,208,79],{"class":67},[61,210,212,214,217,220,222,224,227,229,232,234],{"class":63,"line":211},9,[61,213,122],{"class":67},[61,215,216],{"class":71},"button",[61,218,219],{"class":75}," id",[61,221,93],{"class":71},[61,223,97],{"class":96},[61,225,226],{"class":100},"load-from-api",[61,228,97],{"class":96},[61,230,231],{"class":67},">Carregar dados\u003C\u002F",[61,233,216],{"class":71},[61,235,79],{"class":67},[61,237,239,241,243,245,247,249,252,254,257,259],{"class":63,"line":238},10,[61,240,122],{"class":67},[61,242,216],{"class":71},[61,244,219],{"class":75},[61,246,93],{"class":71},[61,248,97],{"class":96},[61,250,251],{"class":100},"load-all-characters",[61,253,97],{"class":96},[61,255,256],{"class":67},">Carregar todos os personagens\u003C\u002F",[61,258,216],{"class":71},[61,260,79],{"class":67},[61,262,264,266,269,272,274,276,279,281,284,286],{"class":63,"line":263},11,[61,265,122],{"class":67},[61,267,268],{"class":71},"script",[61,270,271],{"class":75}," src",[61,273,93],{"class":71},[61,275,97],{"class":96},[61,277,278],{"class":100},".\u002Fapp.js",[61,280,97],{"class":96},[61,282,283],{"class":67},">\u003C\u002F",[61,285,268],{"class":71},[61,287,79],{"class":67},[61,289,291,293,295],{"class":63,"line":290},12,[61,292,194],{"class":67},[61,294,206],{"class":71},[61,296,79],{"class":67},[61,298,300,303,305],{"class":63,"line":299},13,[61,301,302],{"class":67},"\u003C\u002F",[61,304,46],{"class":71},[61,306,79],{"class":67},[16,308,309],{},"É uma marcação de conteúdo simples, dentro da tag Body se tem dois botões nos quais vamos adicionar eventos de \"click\" no arquivo app.js que é importado logo abaixo os botões nesse código HTML.",[31,311,313],{"id":312},"javascript","JavaScript",[16,315,316],{},"Dentro do arquivo app.js, será realizado os seguintes passos:",[318,319,320,324,327,330],"ol",{},[321,322,323],"li",{},"Capturar o elemento da DOM com id \"load-from-api\" e armazenar em uma variável chamada loadDataBtn.",[321,325,326],{},"Obter a tag HTML da DOM com o id \"load-all-characters\"",[321,328,329],{},"Armazenar a Url da Api do \"Rick and Morty\" em uma variável chamada \"BASE_URL\"",[321,331,332],{},"Adicionar o \"listener\" de evento de click no elemento \"loadDataBtn\" e \"loadAllCharactersBtn\"",[52,334,337],{"className":335,"code":336,"language":312,"meta":56,"style":56},"language-javascript shiki shiki-themes dracula","const loadDataBtn = document.getElementById(\"load-from-api\");\nconst loadAllCharactersBtn = document.getElementById(\"load-all-characters\");\n\nconst BASE_URL = \"https:\u002F\u002Frickandmortyapi.com\u002Fapi\u002Fcharacter\";\n\nloadDataBtn.addEventListener(\"click\", () => {\n  \u002F\u002F Algum código aqui\n});\n\nloadAllCharactersBtn.addEventListener(\"click\", () => {\n  \u002F\u002F Algum código aqui\n});\n",[58,338,339,344,349,355,360,364,369,374,379,383,388,392],{"__ignoreMap":56},[61,340,341],{"class":63,"line":64},[61,342,343],{},"const loadDataBtn = document.getElementById(\"load-from-api\");\n",[61,345,346],{"class":63,"line":82},[61,347,348],{},"const loadAllCharactersBtn = document.getElementById(\"load-all-characters\");\n",[61,350,351],{"class":63,"line":108},[61,352,354],{"emptyLinePlaceholder":353},true,"\n",[61,356,357],{"class":63,"line":119},[61,358,359],{},"const BASE_URL = \"https:\u002F\u002Frickandmortyapi.com\u002Fapi\u002Fcharacter\";\n",[61,361,362],{"class":63,"line":143},[61,363,354],{"emptyLinePlaceholder":353},[61,365,366],{"class":63,"line":176},[61,367,368],{},"loadDataBtn.addEventListener(\"click\", () => {\n",[61,370,371],{"class":63,"line":191},[61,372,373],{},"  \u002F\u002F Algum código aqui\n",[61,375,376],{"class":63,"line":201},[61,377,378],{},"});\n",[61,380,381],{"class":63,"line":211},[61,382,354],{"emptyLinePlaceholder":353},[61,384,385],{"class":63,"line":238},[61,386,387],{},"loadAllCharactersBtn.addEventListener(\"click\", () => {\n",[61,389,390],{"class":63,"line":263},[61,391,373],{},[61,393,394],{"class":63,"line":290},[61,395,378],{},[31,397,399],{"id":398},"carregando-dados-da-api-com-a-fetch-api","Carregando dados da Api com a Fetch Api",[16,401,402],{},"Vamos trabalhar dentro da função que é executada ao clicar no elemento com id \"load-from-api\", mas antes disso é necessário salientar que a Fetch API retorna uma Promise, na qual podemos lidar com ela de duas formas:",[404,405,406,409],"ul",{},[321,407,408],{},"Utilizando Async\u002FAwait",[321,410,411],{},"Utilizando a forma tradicional de lidar com Promises com o \".then\"",[16,413,414],{},"Vamos utilizar o Async\u002FAwait, onde o async será colocado antes da função que lida com o evento de Click e o Await é colocado antes da chamada da Fetch Api:",[52,416,418],{"className":335,"code":417,"language":312,"meta":56,"style":56},"loadAllCharactersBtn.addEventListener(\"click\", async () => {\n  const apiResponse = await fetch(BASE_URL);\n});\n",[58,419,420,425,430],{"__ignoreMap":56},[61,421,422],{"class":63,"line":64},[61,423,424],{},"loadAllCharactersBtn.addEventListener(\"click\", async () => {\n",[61,426,427],{"class":63,"line":82},[61,428,429],{},"  const apiResponse = await fetch(BASE_URL);\n",[61,431,432],{"class":63,"line":108},[61,433,378],{},[16,435,436],{},"Quando se está trabalhando com a Fetch Api, também se faz necessário tratar os dados retornos da API. Nesse exemplo a API retorna JSON, então precisamos tratar o dado como JSON. Importante observar que a função no JavaScript para tratar dados em JSON também retorna uma Promise, por esse motivo também se faz necessário utilizar o await.",[16,438,439],{},"No exemplo foi executado os passos acima mencionados e o dado já preparado para utilização dentro do código JavaScript foi armazenado na variável: \"parsedResponse\".",[52,441,443],{"className":335,"code":442,"language":312,"meta":56,"style":56},"loadDataBtn.addEventListener(\"click\", async () => {\n  const apiResponse = await fetch(BASE_URL);\n  const parsedResponse = await apiResponse.json();\n\n  console.log(\"parsedResponse\");\n  console.log(parsedResponse);\n});\n",[58,444,445,450,454,459,463,468,473],{"__ignoreMap":56},[61,446,447],{"class":63,"line":64},[61,448,449],{},"loadDataBtn.addEventListener(\"click\", async () => {\n",[61,451,452],{"class":63,"line":82},[61,453,429],{},[61,455,456],{"class":63,"line":108},[61,457,458],{},"  const parsedResponse = await apiResponse.json();\n",[61,460,461],{"class":63,"line":119},[61,462,354],{"emptyLinePlaceholder":353},[61,464,465],{"class":63,"line":143},[61,466,467],{},"  console.log(\"parsedResponse\");\n",[61,469,470],{"class":63,"line":176},[61,471,472],{},"  console.log(parsedResponse);\n",[61,474,475],{"class":63,"line":191},[61,476,378],{},[478,479,480],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .s0Tla, html code.shiki .s0Tla{--shiki-default:#FF79C6}html pre.shiki code .sY_PY, html code.shiki .sY_PY{--shiki-default:#50FA7B;--shiki-default-font-style:italic}html pre.shiki code .seVfx, html code.shiki .seVfx{--shiki-default:#E9F284}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}",{"title":56,"searchDepth":82,"depth":82,"links":482},[483,484,485,486],{"id":33,"depth":82,"text":34},{"id":46,"depth":82,"text":47},{"id":312,"depth":82,"text":313},{"id":398,"depth":82,"text":399},[312],"Aprenda a utilizar a Fetch API do JavaScript para consumir uma API real sem bibliotecas extras, com exemplos práticos detalhados em HTML e JavaScript.","md",{},"\u002Fblog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api","2024-09-05",{"title":6,"description":488},{"loc":491,"lastmod":492},"blog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api",361,"gnUiE0KOgnukIf90TtTiXup-L9GmLfQfVNbec_ISIl0",{"id":499,"title":500,"articleCover":501,"articleCoverEmbed":8,"articleCoverEmbedUploadDate":8,"articleCoverHeight":9,"articleCoverWidth":10,"authorId":11,"body":502,"categoriesIds":1319,"description":1321,"enAlternateSlug":1322,"extension":489,"meta":1323,"navigation":353,"path":1324,"ptBrAlternateSlug":1325,"publishedAt":1326,"seo":1327,"sitemap":1328,"stem":1330,"updatedAt":1329,"wordCount":1331,"__hash__":1332},"blog\u002Fblog\u002Fcomo-validar-cartao-de-credito-com-javascript.md","Como validar um cartão de crédito com JavaScript (algoritmo de Luhn)","\u002Fimages\u002Fblog\u002Fjavascript\u002Fcomo-validar-cartao-de-credito-com-javascript.webp",{"type":13,"value":503,"toc":1296},[504,507,510,514,522,525,528,532,542,545,577,582,599,625,631,634,638,641,1104,1121,1125,1136,1153,1159,1162,1166,1169,1173,1180,1184,1197,1201,1204,1208,1215,1224,1228,1232,1243,1247,1250,1254,1257,1261,1264,1268,1271,1275,1278,1282,1285,1293],[16,505,506],{},"Você está construindo um formulário de checkout e precisa validar o campo de cartão antes de enviar os dados pro gateway de pagamento. A solução mais comum e recomendada é usar o algoritmo de Luhn para checar se o número tem o formato matemático correto.",[16,508,509],{},"Neste artigo, você vai entender exatamente como o algoritmo funciona, ver um exemplo numérico passo a passo e implementar uma função JavaScript pronta pra usar no seu projeto.",[31,511,513],{"id":512},"o-que-é-o-algoritmo-de-luhn","O que é o algoritmo de Luhn",[16,515,516,517,521],{},"O algoritmo de Luhn, também chamado de \"fórmula do módulo 10\" ou \"mod-10\", foi criado por Hans Peter Luhn em 1954 e virou padrão da indústria para validar números de cartão de crédito. Ele calcula um ",[518,519,520],"strong",{},"dígito verificador"," (o último dígito do número) que permite detectar erros de digitação, como trocar dois dígitos de lugar ou digitar um número errado.",[16,523,524],{},"A ideia é simples: o emissor do cartão (banco ou bandeira) gera o número de forma que, quando você aplica a fórmula do Luhn, o resultado seja divisível por 10. Se não for, o número tem erro de formatação.",[16,526,527],{},"Isso é feito no lado do cliente (no navegador) antes de mandar os dados pro servidor. Assim você evita enviar requisições inválidas pro gateway de pagamento e melhora a experiência do usuário com feedback imediato.",[31,529,531],{"id":530},"passo-a-passo-do-algoritmo-com-exemplo-numérico","Passo a passo do algoritmo com exemplo numérico",[16,533,534,535,538,539,26],{},"Vamos validar o número de teste da Visa que várias plataformas de pagamento usam em sandbox: ",[518,536,537],{},"4242 4242 4242 4242",". Primeiro, removemos espaços e traços, ficando com ",[58,540,541],{},"4242424242424242",[16,543,544],{},"Agora aplicamos o algoritmo de Luhn:",[318,546,547,553,559,565,571],{},[321,548,549,552],{},[518,550,551],{},"Comece pelo dígito mais à direita"," (o último 2) e vá para a esquerda. Esse primeiro dígito nunca é dobrado.",[321,554,555,558],{},[518,556,557],{},"Dobre o valor de cada segundo dígito"," a partir daí, ou seja, pule um, dobre o próximo, pule um, dobre o próximo, e assim por diante.",[321,560,561,564],{},[518,562,563],{},"Se o dobro resultar em dois dígitos",", some os dois algarismos entre si (ou subtraia 9, é equivalente).",[321,566,567,570],{},[518,568,569],{},"Some todos os dígitos"," (os dobrados\u002Fajustados e os que não foram alterados).",[321,572,573,576],{},[518,574,575],{},"Se o total for divisível por 10",", o número é válido pelo algoritmo de Luhn.",[578,579,581],"h3",{"id":580},"exemplo-prático-com-4242424242424242","Exemplo prático com 4242424242424242",[16,583,584,585,588,589,592,593,595,596,598],{},"O número tem 16 dígitos, alternando ",[58,586,587],{},"4"," e ",[58,590,591],{},"2",". Começando pelo dígito mais à direita (que não é dobrado) e indo para a esquerda, os dígitos que caem na posição \"dobrar\" são sempre os ",[58,594,587],{},", e os que caem na posição \"não dobrar\" são sempre os ",[58,597,591],{},". Isso acontece porque o número inteiro segue esse padrão alternado.",[404,600,601,610],{},[321,602,603,606,607,609],{},[518,604,605],{},"Dígitos que não são dobrados"," (8 dígitos, todos ",[58,608,591],{},"): 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 = 16",[321,611,612,606,615,617,618,620,621,624],{},[518,613,614],{},"Dígitos dobrados",[58,616,587],{},"): cada ",[58,619,587],{}," dobrado vira ",[58,622,623],{},"8"," (4 × 2 = 8, não passa de 9, não precisa ajustar). 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 = 64",[16,626,627,628,26],{},"Somando os dois grupos: 16 + 64 = ",[518,629,630],{},"80",[16,632,633],{},"Como 80 é divisível por 10 (resto 0), esse número passa na validação do algoritmo de Luhn.",[31,635,637],{"id":636},"implementação-em-javascript-puro","Implementação em JavaScript puro",[16,639,640],{},"Abaixo está uma função completa que remove espaços, traços e outros caracteres não numéricos, depois aplica o algoritmo de Luhn:",[52,642,644],{"className":335,"code":643,"language":312,"meta":56,"style":56},"function validarCartaoCredito(numero) {\n  \u002F\u002F Remove tudo que não for dígito\n  const digitos = numero.replace(\u002F\\D\u002Fg, \"\");\n\n  \u002F\u002F Cartões têm entre 13 e 19 dígitos (a maioria 16)\n  if (digitos.length \u003C 13 || digitos.length > 19) {\n    return false;\n  }\n\n  let soma = 0;\n  let deveDobrar = false; \u002F\u002F começa pelo último dígito (não dobra)\n\n  \u002F\u002F Percorre da direita para a esquerda\n  for (let i = digitos.length - 1; i >= 0; i--) {\n    let d = parseInt(digitos[i], 10);\n\n    if (deveDobrar) {\n      d *= 2;\n      \u002F\u002F Se resultou em dois dígitos, soma os algarismos (ou subtrai 9)\n      if (d > 9) {\n        d -= 9;\n      }\n    }\n\n    soma += d;\n    deveDobrar = !deveDobrar; \u002F\u002F alterna para o próximo dígito\n  }\n\n  return soma % 10 === 0;\n}\n\n\u002F\u002F Testando com o número de teste da Visa\nconsole.log(validarCartaoCredito(\"4242 4242 4242 4242\")); \u002F\u002F true\nconsole.log(validarCartaoCredito(\"4242424242424242\")); \u002F\u002F true\nconsole.log(validarCartaoCredito(\"1234 5678 1234 5678\")); \u002F\u002F false\n",[58,645,646,665,671,711,715,720,747,758,763,767,782,799,803,808,849,871,876,885,899,905,921,934,940,946,951,963,980,985,990,1011,1017,1022,1028,1056,1079],{"__ignoreMap":56},[61,647,648,651,655,658,662],{"class":63,"line":64},[61,649,650],{"class":71},"function",[61,652,654],{"class":653},"sAOxA"," validarCartaoCredito",[61,656,657],{"class":67},"(",[61,659,661],{"class":660},"sGEwX","numero",[61,663,664],{"class":67},") {\n",[61,666,667],{"class":63,"line":82},[61,668,670],{"class":669},"shSDL","  \u002F\u002F Remove tudo que não for dígito\n",[61,672,673,676,679,681,684,687,689,693,697,699,702,705,708],{"class":63,"line":108},[61,674,675],{"class":71},"  const",[61,677,678],{"class":67}," digitos ",[61,680,93],{"class":71},[61,682,683],{"class":67}," numero.",[61,685,686],{"class":653},"replace",[61,688,657],{"class":67},[61,690,692],{"class":691},"s-doY","\u002F",[61,694,696],{"class":695},"sIQBb","\\D",[61,698,692],{"class":691},[61,700,701],{"class":71},"g",[61,703,704],{"class":67},", ",[61,706,707],{"class":96},"\"\"",[61,709,710],{"class":67},");\n",[61,712,713],{"class":63,"line":119},[61,714,354],{"emptyLinePlaceholder":353},[61,716,717],{"class":63,"line":143},[61,718,719],{"class":669},"  \u002F\u002F Cartões têm entre 13 e 19 dígitos (a maioria 16)\n",[61,721,722,725,728,730,733,736,739,742,745],{"class":63,"line":176},[61,723,724],{"class":71},"  if",[61,726,727],{"class":67}," (digitos.length ",[61,729,85],{"class":71},[61,731,732],{"class":695}," 13",[61,734,735],{"class":71}," ||",[61,737,738],{"class":67}," digitos.length ",[61,740,741],{"class":71},">",[61,743,744],{"class":695}," 19",[61,746,664],{"class":67},[61,748,749,752,755],{"class":63,"line":191},[61,750,751],{"class":71},"    return",[61,753,754],{"class":695}," false",[61,756,757],{"class":67},";\n",[61,759,760],{"class":63,"line":201},[61,761,762],{"class":67},"  }\n",[61,764,765],{"class":63,"line":211},[61,766,354],{"emptyLinePlaceholder":353},[61,768,769,772,775,777,780],{"class":63,"line":238},[61,770,771],{"class":71},"  let",[61,773,774],{"class":67}," soma ",[61,776,93],{"class":71},[61,778,779],{"class":695}," 0",[61,781,757],{"class":67},[61,783,784,786,789,791,793,796],{"class":63,"line":263},[61,785,771],{"class":71},[61,787,788],{"class":67}," deveDobrar ",[61,790,93],{"class":71},[61,792,754],{"class":695},[61,794,795],{"class":67},"; ",[61,797,798],{"class":669},"\u002F\u002F começa pelo último dígito (não dobra)\n",[61,800,801],{"class":63,"line":290},[61,802,354],{"emptyLinePlaceholder":353},[61,804,805],{"class":63,"line":299},[61,806,807],{"class":669},"  \u002F\u002F Percorre da direita para a esquerda\n",[61,809,811,814,817,820,823,825,827,830,833,836,839,841,844,847],{"class":63,"line":810},14,[61,812,813],{"class":71},"  for",[61,815,816],{"class":67}," (",[61,818,819],{"class":71},"let",[61,821,822],{"class":67}," i ",[61,824,93],{"class":71},[61,826,738],{"class":67},[61,828,829],{"class":71},"-",[61,831,832],{"class":695}," 1",[61,834,835],{"class":67},"; i ",[61,837,838],{"class":71},">=",[61,840,779],{"class":695},[61,842,843],{"class":67},"; i",[61,845,846],{"class":71},"--",[61,848,664],{"class":67},[61,850,852,855,858,860,863,866,869],{"class":63,"line":851},15,[61,853,854],{"class":71},"    let",[61,856,857],{"class":67}," d ",[61,859,93],{"class":71},[61,861,862],{"class":653}," parseInt",[61,864,865],{"class":67},"(digitos[i], ",[61,867,868],{"class":695},"10",[61,870,710],{"class":67},[61,872,874],{"class":63,"line":873},16,[61,875,354],{"emptyLinePlaceholder":353},[61,877,879,882],{"class":63,"line":878},17,[61,880,881],{"class":71},"    if",[61,883,884],{"class":67}," (deveDobrar) {\n",[61,886,888,891,894,897],{"class":63,"line":887},18,[61,889,890],{"class":67},"      d ",[61,892,893],{"class":71},"*=",[61,895,896],{"class":695}," 2",[61,898,757],{"class":67},[61,900,902],{"class":63,"line":901},19,[61,903,904],{"class":669},"      \u002F\u002F Se resultou em dois dígitos, soma os algarismos (ou subtrai 9)\n",[61,906,908,911,914,916,919],{"class":63,"line":907},20,[61,909,910],{"class":71},"      if",[61,912,913],{"class":67}," (d ",[61,915,741],{"class":71},[61,917,918],{"class":695}," 9",[61,920,664],{"class":67},[61,922,924,927,930,932],{"class":63,"line":923},21,[61,925,926],{"class":67},"        d ",[61,928,929],{"class":71},"-=",[61,931,918],{"class":695},[61,933,757],{"class":67},[61,935,937],{"class":63,"line":936},22,[61,938,939],{"class":67},"      }\n",[61,941,943],{"class":63,"line":942},23,[61,944,945],{"class":67},"    }\n",[61,947,949],{"class":63,"line":948},24,[61,950,354],{"emptyLinePlaceholder":353},[61,952,954,957,960],{"class":63,"line":953},25,[61,955,956],{"class":67},"    soma ",[61,958,959],{"class":71},"+=",[61,961,962],{"class":67}," d;\n",[61,964,966,969,971,974,977],{"class":63,"line":965},26,[61,967,968],{"class":67},"    deveDobrar ",[61,970,93],{"class":71},[61,972,973],{"class":71}," !",[61,975,976],{"class":67},"deveDobrar; ",[61,978,979],{"class":669},"\u002F\u002F alterna para o próximo dígito\n",[61,981,983],{"class":63,"line":982},27,[61,984,762],{"class":67},[61,986,988],{"class":63,"line":987},28,[61,989,354],{"emptyLinePlaceholder":353},[61,991,993,996,998,1001,1004,1007,1009],{"class":63,"line":992},29,[61,994,995],{"class":71},"  return",[61,997,774],{"class":67},[61,999,1000],{"class":71},"%",[61,1002,1003],{"class":695}," 10",[61,1005,1006],{"class":71}," ===",[61,1008,779],{"class":695},[61,1010,757],{"class":67},[61,1012,1014],{"class":63,"line":1013},30,[61,1015,1016],{"class":67},"}\n",[61,1018,1020],{"class":63,"line":1019},31,[61,1021,354],{"emptyLinePlaceholder":353},[61,1023,1025],{"class":63,"line":1024},32,[61,1026,1027],{"class":669},"\u002F\u002F Testando com o número de teste da Visa\n",[61,1029,1031,1034,1037,1039,1042,1044,1046,1048,1050,1053],{"class":63,"line":1030},33,[61,1032,1033],{"class":67},"console.",[61,1035,1036],{"class":653},"log",[61,1038,657],{"class":67},[61,1040,1041],{"class":653},"validarCartaoCredito",[61,1043,657],{"class":67},[61,1045,97],{"class":96},[61,1047,537],{"class":100},[61,1049,97],{"class":96},[61,1051,1052],{"class":67},")); ",[61,1054,1055],{"class":669},"\u002F\u002F true\n",[61,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075,1077],{"class":63,"line":1058},34,[61,1060,1033],{"class":67},[61,1062,1036],{"class":653},[61,1064,657],{"class":67},[61,1066,1041],{"class":653},[61,1068,657],{"class":67},[61,1070,97],{"class":96},[61,1072,541],{"class":100},[61,1074,97],{"class":96},[61,1076,1052],{"class":67},[61,1078,1055],{"class":669},[61,1080,1082,1084,1086,1088,1090,1092,1094,1097,1099,1101],{"class":63,"line":1081},35,[61,1083,1033],{"class":67},[61,1085,1036],{"class":653},[61,1087,657],{"class":67},[61,1089,1041],{"class":653},[61,1091,657],{"class":67},[61,1093,97],{"class":96},[61,1095,1096],{"class":100},"1234 5678 1234 5678",[61,1098,97],{"class":96},[61,1100,1052],{"class":67},[61,1102,1103],{"class":669},"\u002F\u002F false\n",[16,1105,1106,1107,1110,1111,1114,1115,1120],{},"Essa função é o que você usa no ",[58,1108,1109],{},"onblur"," ou ",[58,1112,1113],{},"onsubmit"," do seu formulário. Se quiser testar online antes de integrar, temos um ",[20,1116,1119],{"href":1117,"rel":1118},"https:\u002F\u002Fcodigoaoponto.com\u002Fferramentas\u002Fvalidador-de-cartao-de-credito",[24],"validador de cartão de crédito online, gratuito"," que aplica exatamente essa lógica.",[31,1122,1124],{"id":1123},"o-que-esse-algoritmo-não-garante","O que esse algoritmo NÃO garante",[16,1126,1127,1128,1131,1132,1135],{},"Aqui vai o disclaimer que muita gente pula (e depois se arrepende): ",[518,1129,1130],{},"o algoritmo de Luhn valida apenas o FORMATO\u002Festrutura matemática do número",". Ele ",[518,1133,1134],{},"NÃO"," verifica:",[404,1137,1138,1141,1144,1147,1150],{},[321,1139,1140],{},"Se o cartão existe de verdade",[321,1142,1143],{},"Se está ativo ou bloqueado",[321,1145,1146],{},"Se tem limite disponível",[321,1148,1149],{},"Se pertence à pessoa que está preenchendo o formulário",[321,1151,1152],{},"Se não é um cartão reportado como roubado\u002Ffraudado",[16,1154,1155,1156,1158],{},"Isso só o emissor do cartão (banco ou bandeira) consegue checar, via gateway de pagamento real (Stripe, Pagar.me, Mercado Pago, etc.). O Luhn é só um \"filtro de digitação\". Ele evita que você mande ",[58,1157,1096],{}," pro gateway e receba um erro bobo que poderia ter sido pego antes.",[16,1160,1161],{},"Não escreva no seu código nada que sugira que validar com Luhn significa \"cartão válido pra cobrar\", porque não é verdade.",[31,1163,1165],{"id":1164},"erros-comuns","Erros comuns",[16,1167,1168],{},"Se você já implementou validação de cartão, provavelmente já viu (ou cometeu) algum desses:",[578,1170,1172],{"id":1171},"validar-só-pela-quantidade-de-dígitos","Validar só pela quantidade de dígitos",[16,1174,1175,1176,1179],{},"Muitos formulários só checam se o número tem 16 dígitos. Isso deixa passar ",[58,1177,1178],{},"1111111111111111",", que tem 16 dígitos mas falha no Luhn. O inverso também acontece: American Express tem 15 dígitos, então validar só por \"tem que ter 16\" quebra o fluxo pra quem usa Amex.",[578,1181,1183],{"id":1182},"não-remover-espaçostraços-antes-de-validar","Não remover espaços\u002Ftraços antes de validar",[16,1185,1186,1187,1110,1190,1192,1193,1196],{},"O usuário digita ",[58,1188,1189],{},"4242-4242-4242-4242",[58,1191,537],{},". Se você não limpar isso antes de aplicar o Luhn, a validação falha mesmo com o número correto. A linha ",[58,1194,1195],{},"numero.replace(\u002F\\D\u002Fg, '')"," resolve isso.",[578,1198,1200],{"id":1199},"tratar-luhn-como-verificação-antifraude","Tratar Luhn como verificação antifraude",[16,1202,1203],{},"Isso é clássico: o time de produto pede \"valida se o cartão é válido\" e o dev implementa Luhn achando que tá fazendo verificação de fraude. Não tá. Fraude requer análise de risco, tokenização, 3D Secure, regras do gateway. Nada disso o Luhn faz.",[578,1205,1207],{"id":1206},"usar-números-de-teste-como-se-fossem-reais","Usar números de teste como se fossem reais",[16,1209,1210,1211,1214],{},"Os números de teste que gateways como Stripe e PayPal disponibilizam são válidos pelo Luhn, mas ",[518,1212,1213],{},"não são cartões reais",". Eles só funcionam em ambiente de sandbox. Nunca use em produção e nunca tente \"testar se funciona\" em gateway real. Isso é violação dos termos e pode gerar bloqueio.",[16,1216,1217,1218,1223],{},"Se precisar de dados de teste válidos pelo Luhn pra testar formulários, nosso ",[20,1219,1222],{"href":1220,"rel":1221},"https:\u002F\u002Fcodigoaoponto.com\u002Fferramentas\u002Fgerador-de-cartao-de-credito",[24],"gerador de cartão de crédito para testes"," cria números estruturalmente corretos (mas não reais) pra você usar no QA.",[31,1225,1227],{"id":1226},"perguntas-frequentes","Perguntas frequentes",[578,1229,1231],{"id":1230},"como-saber-se-um-número-de-cartão-é-válido","Como saber se um número de cartão é válido?",[16,1233,1234,1235,1238,1239,1242],{},"Depende do que você quer dizer com \"válido\". Se for ",[518,1236,1237],{},"formato correto",", use o algoritmo de Luhn, que é o que a maioria dos gateways espera no front-end. Se for ",[518,1240,1241],{},"cartão que realmente funciona",", só o gateway de pagamento (via emissor) consegue responder, depois que você tenta cobrar.",[578,1244,1246],{"id":1245},"dá-pra-testar-um-formulário-de-pagamento-sem-usar-cartão-real","Dá pra testar um formulário de pagamento sem usar cartão real?",[16,1248,1249],{},"Sim. Use os números de teste que cada gateway fornece (Stripe, Pagar.me, Mercado Pago, etc.). Eles são válidos pelo Luhn e simulam cenários como \"pagamento aprovado\", \"saldo insuficiente\", \"3D Secure\", etc. Nunca use cartões reais de terceiros. Use só os de sandbox.",[578,1251,1253],{"id":1252},"validar-cartão-de-crédito-é-a-mesma-coisa-que-verificar-se-ele-está-ativo","Validar cartão de crédito é a mesma coisa que verificar se ele está ativo?",[16,1255,1256],{},"Não. Validar (com Luhn) checa se o número tem a estrutura matemática correta. Verificar se está ativo, tem limite ou não tá bloqueado é papel do banco, feito via gateway, quando você tenta processar o pagamento.",[578,1258,1260],{"id":1259},"o-que-é-o-algoritmo-de-luhn-1","O que é o algoritmo de Luhn?",[16,1262,1263],{},"É uma fórmula matemática (módulo 10) que calcula um dígito verificador pra detectar erros de digitação em números como cartões de crédito, IMEI de celular, etc. Foi criado em 1954 por Hans Peter Luhn e virou padrão da indústria.",[578,1265,1267],{"id":1266},"posso-usar-o-luhn-pra-evitar-fraude","Posso usar o Luhn pra evitar fraude?",[16,1269,1270],{},"Não. O Luhn só pega erro de digitação. Fraude requer análise comportamental, verificação de endereço, 3D Secure, regras de risco do gateway. Nada disso o Luhn faz.",[578,1272,1274],{"id":1273},"qual-a-diferença-entre-número-válido-pelo-luhn-e-cartão-válido-pra-cobrar","Qual a diferença entre \"número válido pelo Luhn\" e \"cartão válido pra cobrar\"?",[16,1276,1277],{},"\"Número válido pelo Luhn\" significa formato matemático correto. \"Cartão válido pra cobrar\" significa que o emissor confirmou que o cartão existe, tá ativo, tem limite e não tá bloqueado. Só o gateway junto com o emissor respondem a segunda pergunta.",[31,1279,1281],{"id":1280},"fechamento","Fechamento",[16,1283,1284],{},"Se você tá implementando validação de cartão num formulário de checkout, o algoritmo de Luhn é o primeiro passo, e o mais importante, pra evitar erros bobos de digitação. Implemente a função acima, teste com os números de sandbox do seu gateway e lembre sempre: Luhn valida formato, não valida se o cartão funciona de verdade.",[16,1286,1287,1288,1292],{},"Quer testar sua implementação antes de subir pra produção? Experimente nosso ",[20,1289,1291],{"href":1117,"rel":1290},[24],"validador de cartão de crédito online",". Ele aplica exatamente a mesma lógica que você vai usar no código.",[478,1294,1295],{},"html pre.shiki code .s0Tla, html code.shiki .s0Tla{--shiki-default:#FF79C6}html pre.shiki code .sAOxA, html code.shiki .sAOxA{--shiki-default:#50FA7B}html pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .sGEwX, html code.shiki .sGEwX{--shiki-default:#FFB86C;--shiki-default-font-style:italic}html pre.shiki code .shSDL, html code.shiki .shSDL{--shiki-default:#6272A4}html pre.shiki code .s-doY, html code.shiki .s-doY{--shiki-default:#FF5555}html pre.shiki code .sIQBb, html code.shiki .sIQBb{--shiki-default:#BD93F9}html pre.shiki code .seVfx, html code.shiki .seVfx{--shiki-default:#E9F284}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":56,"searchDepth":82,"depth":82,"links":1297},[1298,1299,1302,1303,1304,1310,1318],{"id":512,"depth":82,"text":513},{"id":530,"depth":82,"text":531,"children":1300},[1301],{"id":580,"depth":108,"text":581},{"id":636,"depth":82,"text":637},{"id":1123,"depth":82,"text":1124},{"id":1164,"depth":82,"text":1165,"children":1305},[1306,1307,1308,1309],{"id":1171,"depth":108,"text":1172},{"id":1182,"depth":108,"text":1183},{"id":1199,"depth":108,"text":1200},{"id":1206,"depth":108,"text":1207},{"id":1226,"depth":82,"text":1227,"children":1311},[1312,1313,1314,1315,1316,1317],{"id":1230,"depth":108,"text":1231},{"id":1245,"depth":108,"text":1246},{"id":1252,"depth":108,"text":1253},{"id":1259,"depth":108,"text":1260},{"id":1266,"depth":108,"text":1267},{"id":1273,"depth":108,"text":1274},{"id":1280,"depth":82,"text":1281},[312,1320],"tools","Aprenda a validar número de cartão de crédito com JavaScript usando o algoritmo de Luhn. Exemplo prático, código pronto e o que o Luhn não verifica.","how-to-validate-credit-card-with-javascript",{},"\u002Fblog\u002Fcomo-validar-cartao-de-credito-com-javascript","como-validar-cartao-de-credito-com-javascript","2026-09-17",{"title":500,"description":1321},{"loc":1324,"lastmod":1329},"2026-10-04","blog\u002Fcomo-validar-cartao-de-credito-com-javascript",1371,"hA78wl69-79iJWs-Nns0eW6ApCJtsUzM8PcjDGtC1PA",{"id":1334,"title":1335,"articleCover":1336,"articleCoverEmbed":8,"articleCoverEmbedUploadDate":8,"articleCoverHeight":9,"articleCoverWidth":10,"authorId":11,"body":1337,"categoriesIds":2702,"description":2703,"enAlternateSlug":2704,"extension":489,"meta":2705,"navigation":353,"path":2706,"ptBrAlternateSlug":2707,"publishedAt":1326,"seo":2708,"sitemap":2709,"stem":2710,"updatedAt":1329,"wordCount":2711,"__hash__":2712},"blog\u002Fblog\u002Fcomo-validar-cpf-com-javascript.md","Como validar um CPF com JavaScript","\u002Fimages\u002Fblog\u002Fjavascript\u002Fcomo-validar-cpf-com-javascript.webp",{"type":13,"value":1338,"toc":2679},[1339,1342,1349,1353,1356,1364,1367,1370,1374,1377,1385,1388,1394,1397,1403,1406,1412,1415,1421,1424,1430,1435,1439,1442,1448,1451,1457,1460,1466,1469,1475,1478,1484,1491,1496,1499,1501,1508,1511,1988,1991,2109,2121,2124,2147,2153,2160,2168,2172,2175,2367,2370,2372,2376,2379,2419,2426,2433,2437,2440,2447,2474,2481,2484,2488,2491,2494,2528,2531,2535,2538,2541,2543,2547,2550,2557,2560,2564,2567,2581,2584,2587,2619,2623,2626,2629,2632,2636,2645,2648,2652,2655,2658,2662,2668,2676],[16,1340,1341],{},"Validar CPF no front-end ajuda a evitar erros em formulários de cadastro, checkout e login. No back-end, a validação é uma segunda barreira contra dados digitados incorretamente e fraudes mais básicas.",[16,1343,1344,1345,1348],{},"Neste artigo, você vai entender o algoritmo do CPF e implementar uma função de ",[518,1346,1347],{},"validação de CPF"," em JavaScript puro, sem biblioteca externa.",[31,1350,1352],{"id":1351},"o-que-são-os-dígitos-verificadores","O que são os dígitos verificadores",[16,1354,1355],{},"Um CPF tem 11 dígitos:",[404,1357,1358,1361],{},[321,1359,1360],{},"Os 9 primeiros são a base do documento.",[321,1362,1363],{},"Os 2 últimos são os dígitos verificadores.",[16,1365,1366],{},"Esses dois dígitos são calculados a partir dos anteriores. A ideia é detectar erros comuns de digitação, como trocar ou remover um número.",[16,1368,1369],{},"A validação matemática, porém, não confirma se o CPF existe, pertence a determinada pessoa ou está regular na Receita Federal. Ela apenas verifica se os dígitos obedecem ao algoritmo do CPF.",[578,1371,1373],{"id":1372},"primeiro-dígito-verificador","Primeiro dígito verificador",[16,1375,1376],{},"Considere o CPF sem formatação:",[52,1378,1383],{"className":1379,"code":1381,"language":1382,"meta":56},[1380],"language-text","52998224725\n","text",[58,1384,1381],{"__ignoreMap":56},[16,1386,1387],{},"Os 9 primeiros dígitos são:",[52,1389,1392],{"className":1390,"code":1391,"language":1382,"meta":56},[1380],"5 2 9 9 8 2 2 4 7\n",[58,1393,1391],{"__ignoreMap":56},[16,1395,1396],{},"Multiplicamos cada número pelos pesos de 10 a 2:",[52,1398,1401],{"className":1399,"code":1400,"language":1382,"meta":56},[1380],"5×10 + 2×9 + 9×8 + 9×7 + 8×6 + 2×5 + 2×4 + 4×3 + 7×2\n",[58,1402,1400],{"__ignoreMap":56},[16,1404,1405],{},"O resultado é:",[52,1407,1410],{"className":1408,"code":1409,"language":1382,"meta":56},[1380],"50 + 18 + 72 + 63 + 48 + 10 + 8 + 12 + 14 = 295\n",[58,1411,1409],{"__ignoreMap":56},[16,1413,1414],{},"Agora calculamos o resto da divisão por 11:",[52,1416,1419],{"className":1417,"code":1418,"language":1382,"meta":56},[1380],"295 % 11 = 9\n",[58,1420,1418],{"__ignoreMap":56},[16,1422,1423],{},"Como o resto é maior que 1, fazemos:",[52,1425,1428],{"className":1426,"code":1427,"language":1382,"meta":56},[1380],"11 - 9 = 2\n",[58,1429,1427],{"__ignoreMap":56},[16,1431,1432,1433,26],{},"Portanto, o primeiro dígito verificador é ",[58,1434,591],{},[578,1436,1438],{"id":1437},"segundo-dígito-verificador","Segundo dígito verificador",[16,1440,1441],{},"Agora usamos os 10 primeiros dígitos, incluindo o verificador calculado:",[52,1443,1446],{"className":1444,"code":1445,"language":1382,"meta":56},[1380],"5 2 9 9 8 2 2 4 7 2\n",[58,1447,1445],{"__ignoreMap":56},[16,1449,1450],{},"Aplicamos os pesos de 11 a 2:",[52,1452,1455],{"className":1453,"code":1454,"language":1382,"meta":56},[1380],"5×11 + 2×10 + 9×9 + 9×8 + 8×7 + 2×6 + 2×5 + 4×4 + 7×3 + 2×2\n",[58,1456,1454],{"__ignoreMap":56},[16,1458,1459],{},"A soma fica:",[52,1461,1464],{"className":1462,"code":1463,"language":1382,"meta":56},[1380],"55 + 20 + 81 + 72 + 56 + 12 + 10 + 16 + 21 + 4 = 347\n",[58,1465,1463],{"__ignoreMap":56},[16,1467,1468],{},"O resto da divisão por 11 é:",[52,1470,1473],{"className":1471,"code":1472,"language":1382,"meta":56},[1380],"347 % 11 = 6\n",[58,1474,1472],{"__ignoreMap":56},[16,1476,1477],{},"Como o resto é maior que 1:",[52,1479,1482],{"className":1480,"code":1481,"language":1382,"meta":56},[1380],"11 - 6 = 5\n",[58,1483,1481],{"__ignoreMap":56},[16,1485,1486,1487,1490],{},"O segundo dígito verificador é ",[58,1488,1489],{},"5",". Assim, o CPF completo é:",[52,1492,1494],{"className":1493,"code":1381,"language":1382,"meta":56},[1380],[58,1495,1381],{"__ignoreMap":56},[16,1497,1498],{},"Esse é o algoritmo do CPF: calcular o primeiro dígito, incorporá-lo à sequência e calcular o segundo.",[31,1500,637],{"id":636},[16,1502,1503,1504,1507],{},"A função precisa lidar com entradas formatadas, como ",[58,1505,1506],{},"529.982.247-25",", e também com uma sequência de números sem pontuação.",[16,1509,1510],{},"Uma implementação possível é esta:",[52,1512,1514],{"className":335,"code":1513,"language":312,"meta":56,"style":56},"function validarCPF(cpf) {\n  \u002F\u002F Garante que a entrada seja tratada como texto\n  cpf = String(cpf).replace(\u002F\\D\u002Fg, \"\");\n\n  \u002F\u002F Um CPF válido deve ter exatamente 11 dígitos\n  if (cpf.length !== 11) {\n    return false;\n  }\n\n  \u002F\u002F Rejeita CPFs formados pelo mesmo dígito\n  if (\u002F^(\\d)\\1{10}$\u002F.test(cpf)) {\n    return false;\n  }\n\n  \u002F\u002F Calcula o primeiro dígito verificador\n  let soma = 0;\n\n  for (let i = 0; i \u003C 9; i++) {\n    soma += Number(cpf[i]) * (10 - i);\n  }\n\n  let resto = soma % 11;\n  const primeiroDigito = resto \u003C 2 ? 0 : 11 - resto;\n\n  \u002F\u002F O primeiro dígito calculado deve ser igual ao informado\n  if (primeiroDigito !== Number(cpf[9])) {\n    return false;\n  }\n\n  \u002F\u002F Calcula o segundo dígito verificador\n  soma = 0;\n\n  for (let i = 0; i \u003C 10; i++) {\n    soma += Number(cpf[i]) * (11 - i);\n  }\n\n  resto = soma % 11;\n  const segundoDigito = resto \u003C 2 ? 0 : 11 - resto;\n\n  \u002F\u002F O segundo dígito calculado também deve ser igual ao informado\n  return segundoDigito === Number(cpf[10]);\n}\n",[58,1515,1516,1530,1535,1566,1570,1575,1590,1598,1602,1606,1611,1644,1652,1656,1660,1665,1677,1681,1708,1733,1737,1741,1758,1788,1792,1797,1817,1825,1829,1833,1838,1849,1853,1879,1900,1904,1909,1925,1953,1958,1964,1983],{"__ignoreMap":56},[61,1517,1518,1520,1523,1525,1528],{"class":63,"line":64},[61,1519,650],{"class":71},[61,1521,1522],{"class":653}," validarCPF",[61,1524,657],{"class":67},[61,1526,1527],{"class":660},"cpf",[61,1529,664],{"class":67},[61,1531,1532],{"class":63,"line":82},[61,1533,1534],{"class":669},"  \u002F\u002F Garante que a entrada seja tratada como texto\n",[61,1536,1537,1540,1542,1545,1548,1550,1552,1554,1556,1558,1560,1562,1564],{"class":63,"line":108},[61,1538,1539],{"class":67},"  cpf ",[61,1541,93],{"class":71},[61,1543,1544],{"class":653}," String",[61,1546,1547],{"class":67},"(cpf).",[61,1549,686],{"class":653},[61,1551,657],{"class":67},[61,1553,692],{"class":691},[61,1555,696],{"class":695},[61,1557,692],{"class":691},[61,1559,701],{"class":71},[61,1561,704],{"class":67},[61,1563,707],{"class":96},[61,1565,710],{"class":67},[61,1567,1568],{"class":63,"line":119},[61,1569,354],{"emptyLinePlaceholder":353},[61,1571,1572],{"class":63,"line":143},[61,1573,1574],{"class":669},"  \u002F\u002F Um CPF válido deve ter exatamente 11 dígitos\n",[61,1576,1577,1579,1582,1585,1588],{"class":63,"line":176},[61,1578,724],{"class":71},[61,1580,1581],{"class":67}," (cpf.length ",[61,1583,1584],{"class":71},"!==",[61,1586,1587],{"class":695}," 11",[61,1589,664],{"class":67},[61,1591,1592,1594,1596],{"class":63,"line":191},[61,1593,751],{"class":71},[61,1595,754],{"class":695},[61,1597,757],{"class":67},[61,1599,1600],{"class":63,"line":201},[61,1601,762],{"class":67},[61,1603,1604],{"class":63,"line":211},[61,1605,354],{"emptyLinePlaceholder":353},[61,1607,1608],{"class":63,"line":238},[61,1609,1610],{"class":669},"  \u002F\u002F Rejeita CPFs formados pelo mesmo dígito\n",[61,1612,1613,1615,1617,1619,1622,1625,1628,1631,1634,1636,1638,1641],{"class":63,"line":263},[61,1614,724],{"class":71},[61,1616,816],{"class":67},[61,1618,692],{"class":691},[61,1620,1621],{"class":71},"^",[61,1623,657],{"class":1624},"smvxG",[61,1626,1627],{"class":695},"\\d",[61,1629,1630],{"class":1624},")",[61,1632,1633],{"class":71},"\\1{10}$",[61,1635,692],{"class":691},[61,1637,26],{"class":67},[61,1639,1640],{"class":653},"test",[61,1642,1643],{"class":67},"(cpf)) {\n",[61,1645,1646,1648,1650],{"class":63,"line":290},[61,1647,751],{"class":71},[61,1649,754],{"class":695},[61,1651,757],{"class":67},[61,1653,1654],{"class":63,"line":299},[61,1655,762],{"class":67},[61,1657,1658],{"class":63,"line":810},[61,1659,354],{"emptyLinePlaceholder":353},[61,1661,1662],{"class":63,"line":851},[61,1663,1664],{"class":669},"  \u002F\u002F Calcula o primeiro dígito verificador\n",[61,1666,1667,1669,1671,1673,1675],{"class":63,"line":873},[61,1668,771],{"class":71},[61,1670,774],{"class":67},[61,1672,93],{"class":71},[61,1674,779],{"class":695},[61,1676,757],{"class":67},[61,1678,1679],{"class":63,"line":878},[61,1680,354],{"emptyLinePlaceholder":353},[61,1682,1683,1685,1687,1689,1691,1693,1695,1697,1699,1701,1703,1706],{"class":63,"line":887},[61,1684,813],{"class":71},[61,1686,816],{"class":67},[61,1688,819],{"class":71},[61,1690,822],{"class":67},[61,1692,93],{"class":71},[61,1694,779],{"class":695},[61,1696,835],{"class":67},[61,1698,85],{"class":71},[61,1700,918],{"class":695},[61,1702,843],{"class":67},[61,1704,1705],{"class":71},"++",[61,1707,664],{"class":67},[61,1709,1710,1712,1714,1717,1720,1723,1725,1727,1730],{"class":63,"line":901},[61,1711,956],{"class":67},[61,1713,959],{"class":71},[61,1715,1716],{"class":653}," Number",[61,1718,1719],{"class":67},"(cpf[i]) ",[61,1721,1722],{"class":71},"*",[61,1724,816],{"class":67},[61,1726,868],{"class":695},[61,1728,1729],{"class":71}," -",[61,1731,1732],{"class":67}," i);\n",[61,1734,1735],{"class":63,"line":907},[61,1736,762],{"class":67},[61,1738,1739],{"class":63,"line":923},[61,1740,354],{"emptyLinePlaceholder":353},[61,1742,1743,1745,1748,1750,1752,1754,1756],{"class":63,"line":936},[61,1744,771],{"class":71},[61,1746,1747],{"class":67}," resto ",[61,1749,93],{"class":71},[61,1751,774],{"class":67},[61,1753,1000],{"class":71},[61,1755,1587],{"class":695},[61,1757,757],{"class":67},[61,1759,1760,1762,1765,1767,1769,1771,1773,1776,1778,1781,1783,1785],{"class":63,"line":942},[61,1761,675],{"class":71},[61,1763,1764],{"class":67}," primeiroDigito ",[61,1766,93],{"class":71},[61,1768,1747],{"class":67},[61,1770,85],{"class":71},[61,1772,896],{"class":695},[61,1774,1775],{"class":71}," ?",[61,1777,779],{"class":695},[61,1779,1780],{"class":71}," :",[61,1782,1587],{"class":695},[61,1784,1729],{"class":71},[61,1786,1787],{"class":67}," resto;\n",[61,1789,1790],{"class":63,"line":948},[61,1791,354],{"emptyLinePlaceholder":353},[61,1793,1794],{"class":63,"line":953},[61,1795,1796],{"class":669},"  \u002F\u002F O primeiro dígito calculado deve ser igual ao informado\n",[61,1798,1799,1801,1804,1806,1808,1811,1814],{"class":63,"line":965},[61,1800,724],{"class":71},[61,1802,1803],{"class":67}," (primeiroDigito ",[61,1805,1584],{"class":71},[61,1807,1716],{"class":653},[61,1809,1810],{"class":67},"(cpf[",[61,1812,1813],{"class":695},"9",[61,1815,1816],{"class":67},"])) {\n",[61,1818,1819,1821,1823],{"class":63,"line":982},[61,1820,751],{"class":71},[61,1822,754],{"class":695},[61,1824,757],{"class":67},[61,1826,1827],{"class":63,"line":987},[61,1828,762],{"class":67},[61,1830,1831],{"class":63,"line":992},[61,1832,354],{"emptyLinePlaceholder":353},[61,1834,1835],{"class":63,"line":1013},[61,1836,1837],{"class":669},"  \u002F\u002F Calcula o segundo dígito verificador\n",[61,1839,1840,1843,1845,1847],{"class":63,"line":1019},[61,1841,1842],{"class":67},"  soma ",[61,1844,93],{"class":71},[61,1846,779],{"class":695},[61,1848,757],{"class":67},[61,1850,1851],{"class":63,"line":1024},[61,1852,354],{"emptyLinePlaceholder":353},[61,1854,1855,1857,1859,1861,1863,1865,1867,1869,1871,1873,1875,1877],{"class":63,"line":1030},[61,1856,813],{"class":71},[61,1858,816],{"class":67},[61,1860,819],{"class":71},[61,1862,822],{"class":67},[61,1864,93],{"class":71},[61,1866,779],{"class":695},[61,1868,835],{"class":67},[61,1870,85],{"class":71},[61,1872,1003],{"class":695},[61,1874,843],{"class":67},[61,1876,1705],{"class":71},[61,1878,664],{"class":67},[61,1880,1881,1883,1885,1887,1889,1891,1893,1896,1898],{"class":63,"line":1058},[61,1882,956],{"class":67},[61,1884,959],{"class":71},[61,1886,1716],{"class":653},[61,1888,1719],{"class":67},[61,1890,1722],{"class":71},[61,1892,816],{"class":67},[61,1894,1895],{"class":695},"11",[61,1897,1729],{"class":71},[61,1899,1732],{"class":67},[61,1901,1902],{"class":63,"line":1081},[61,1903,762],{"class":67},[61,1905,1907],{"class":63,"line":1906},36,[61,1908,354],{"emptyLinePlaceholder":353},[61,1910,1912,1915,1917,1919,1921,1923],{"class":63,"line":1911},37,[61,1913,1914],{"class":67},"  resto ",[61,1916,93],{"class":71},[61,1918,774],{"class":67},[61,1920,1000],{"class":71},[61,1922,1587],{"class":695},[61,1924,757],{"class":67},[61,1926,1928,1930,1933,1935,1937,1939,1941,1943,1945,1947,1949,1951],{"class":63,"line":1927},38,[61,1929,675],{"class":71},[61,1931,1932],{"class":67}," segundoDigito ",[61,1934,93],{"class":71},[61,1936,1747],{"class":67},[61,1938,85],{"class":71},[61,1940,896],{"class":695},[61,1942,1775],{"class":71},[61,1944,779],{"class":695},[61,1946,1780],{"class":71},[61,1948,1587],{"class":695},[61,1950,1729],{"class":71},[61,1952,1787],{"class":67},[61,1954,1956],{"class":63,"line":1955},39,[61,1957,354],{"emptyLinePlaceholder":353},[61,1959,1961],{"class":63,"line":1960},40,[61,1962,1963],{"class":669},"  \u002F\u002F O segundo dígito calculado também deve ser igual ao informado\n",[61,1965,1967,1969,1971,1974,1976,1978,1980],{"class":63,"line":1966},41,[61,1968,995],{"class":71},[61,1970,1932],{"class":67},[61,1972,1973],{"class":71},"===",[61,1975,1716],{"class":653},[61,1977,1810],{"class":67},[61,1979,868],{"class":695},[61,1981,1982],{"class":67},"]);\n",[61,1984,1986],{"class":63,"line":1985},42,[61,1987,1016],{"class":67},[16,1989,1990],{},"Exemplos de uso:",[52,1992,1994],{"className":335,"code":1993,"language":312,"meta":56,"style":56},"console.log(validarCPF(\"529.982.247-25\"));\n\u002F\u002F true\n\nconsole.log(validarCPF(\"52998224725\"));\n\u002F\u002F true\n\nconsole.log(validarCPF(\"529.982.247-26\"));\n\u002F\u002F false\n\nconsole.log(validarCPF(\"111.111.111-11\"));\n\u002F\u002F false\n",[58,1995,1996,2018,2022,2026,2047,2051,2055,2076,2080,2084,2105],{"__ignoreMap":56},[61,1997,1998,2000,2002,2004,2007,2009,2011,2013,2015],{"class":63,"line":64},[61,1999,1033],{"class":67},[61,2001,1036],{"class":653},[61,2003,657],{"class":67},[61,2005,2006],{"class":653},"validarCPF",[61,2008,657],{"class":67},[61,2010,97],{"class":96},[61,2012,1506],{"class":100},[61,2014,97],{"class":96},[61,2016,2017],{"class":67},"));\n",[61,2019,2020],{"class":63,"line":82},[61,2021,1055],{"class":669},[61,2023,2024],{"class":63,"line":108},[61,2025,354],{"emptyLinePlaceholder":353},[61,2027,2028,2030,2032,2034,2036,2038,2040,2043,2045],{"class":63,"line":119},[61,2029,1033],{"class":67},[61,2031,1036],{"class":653},[61,2033,657],{"class":67},[61,2035,2006],{"class":653},[61,2037,657],{"class":67},[61,2039,97],{"class":96},[61,2041,2042],{"class":100},"52998224725",[61,2044,97],{"class":96},[61,2046,2017],{"class":67},[61,2048,2049],{"class":63,"line":143},[61,2050,1055],{"class":669},[61,2052,2053],{"class":63,"line":176},[61,2054,354],{"emptyLinePlaceholder":353},[61,2056,2057,2059,2061,2063,2065,2067,2069,2072,2074],{"class":63,"line":191},[61,2058,1033],{"class":67},[61,2060,1036],{"class":653},[61,2062,657],{"class":67},[61,2064,2006],{"class":653},[61,2066,657],{"class":67},[61,2068,97],{"class":96},[61,2070,2071],{"class":100},"529.982.247-26",[61,2073,97],{"class":96},[61,2075,2017],{"class":67},[61,2077,2078],{"class":63,"line":201},[61,2079,1103],{"class":669},[61,2081,2082],{"class":63,"line":211},[61,2083,354],{"emptyLinePlaceholder":353},[61,2085,2086,2088,2090,2092,2094,2096,2098,2101,2103],{"class":63,"line":238},[61,2087,1033],{"class":67},[61,2089,1036],{"class":653},[61,2091,657],{"class":67},[61,2093,2006],{"class":653},[61,2095,657],{"class":67},[61,2097,97],{"class":96},[61,2099,2100],{"class":100},"111.111.111-11",[61,2102,97],{"class":96},[61,2104,2017],{"class":67},[61,2106,2107],{"class":63,"line":263},[61,2108,1103],{"class":669},[16,2110,2111,2112,2115,2116,2118,2119,26],{},"O trecho ",[58,2113,2114],{},"replace(\u002F\\D\u002Fg, '')"," remove tudo que não for dígito. Isso permite aceitar tanto ",[58,2117,1506],{}," quanto ",[58,2120,2042],{},[16,2122,2123],{},"A expressão regular usada para dígitos repetidos merece atenção:",[52,2125,2127],{"className":335,"code":2126,"language":312,"meta":56,"style":56},"\u002F^(\\d)\\1{10}$\u002F;\n",[58,2128,2129],{"__ignoreMap":56},[61,2130,2131,2133,2135,2137,2139,2141,2143,2145],{"class":63,"line":64},[61,2132,692],{"class":691},[61,2134,1621],{"class":71},[61,2136,657],{"class":1624},[61,2138,1627],{"class":695},[61,2140,1630],{"class":1624},[61,2142,1633],{"class":71},[61,2144,692],{"class":691},[61,2146,757],{"class":67},[16,2148,2149,2150,2152],{},"Ela identifica uma sequência de 11 caracteres formada pelo mesmo dígito. Isso impede que valores como ",[58,2151,2100],{}," sejam aceitos.",[16,2154,2155,2156,2159],{},"Esse é um detalhe que costuma pegar quem já bateu cabeça com o problema: CPFs com todos os dígitos iguais passam pela conta matemática, mas devem ser rejeitados explicitamente. Se você implementar apenas os cálculos, ",[58,2157,2158],{},"11111111111"," será considerado válido pelo seu código.",[16,2161,2162,2163,26],{},"Se quiser testar entradas rapidamente sem criar um formulário, use ",[20,2164,2167],{"href":2165,"rel":2166},"https:\u002F\u002Fcodigoaoponto.com\u002Fferramentas\u002Fvalidador-de-cpf",[24],"nosso validador de CPF online, gratuito",[578,2169,2171],{"id":2170},"validação-no-formulário","Validação no formulário",[16,2173,2174],{},"Você pode chamar a função no evento de envio do formulário:",[52,2176,2178],{"className":335,"code":2177,"language":312,"meta":56,"style":56},"const formulario = document.querySelector(\"#formulario\");\nconst campoCPF = document.querySelector(\"#cpf\");\nconst mensagem = document.querySelector(\"#mensagem\");\n\nformulario.addEventListener(\"submit\", function (evento) {\n  evento.preventDefault();\n\n  if (!validarCPF(campoCPF.value)) {\n    mensagem.textContent = \"Informe um CPF válido.\";\n    return;\n  }\n\n  mensagem.textContent = \"CPF válido.\";\n});\n",[58,2179,2180,2207,2231,2255,2259,2287,2298,2302,2316,2333,2339,2343,2347,2363],{"__ignoreMap":56},[61,2181,2182,2185,2188,2190,2193,2196,2198,2200,2203,2205],{"class":63,"line":64},[61,2183,2184],{"class":71},"const",[61,2186,2187],{"class":67}," formulario ",[61,2189,93],{"class":71},[61,2191,2192],{"class":67}," document.",[61,2194,2195],{"class":653},"querySelector",[61,2197,657],{"class":67},[61,2199,97],{"class":96},[61,2201,2202],{"class":100},"#formulario",[61,2204,97],{"class":96},[61,2206,710],{"class":67},[61,2208,2209,2211,2214,2216,2218,2220,2222,2224,2227,2229],{"class":63,"line":82},[61,2210,2184],{"class":71},[61,2212,2213],{"class":67}," campoCPF ",[61,2215,93],{"class":71},[61,2217,2192],{"class":67},[61,2219,2195],{"class":653},[61,2221,657],{"class":67},[61,2223,97],{"class":96},[61,2225,2226],{"class":100},"#cpf",[61,2228,97],{"class":96},[61,2230,710],{"class":67},[61,2232,2233,2235,2238,2240,2242,2244,2246,2248,2251,2253],{"class":63,"line":108},[61,2234,2184],{"class":71},[61,2236,2237],{"class":67}," mensagem ",[61,2239,93],{"class":71},[61,2241,2192],{"class":67},[61,2243,2195],{"class":653},[61,2245,657],{"class":67},[61,2247,97],{"class":96},[61,2249,2250],{"class":100},"#mensagem",[61,2252,97],{"class":96},[61,2254,710],{"class":67},[61,2256,2257],{"class":63,"line":119},[61,2258,354],{"emptyLinePlaceholder":353},[61,2260,2261,2264,2267,2269,2271,2274,2276,2278,2280,2282,2285],{"class":63,"line":143},[61,2262,2263],{"class":67},"formulario.",[61,2265,2266],{"class":653},"addEventListener",[61,2268,657],{"class":67},[61,2270,97],{"class":96},[61,2272,2273],{"class":100},"submit",[61,2275,97],{"class":96},[61,2277,704],{"class":67},[61,2279,650],{"class":71},[61,2281,816],{"class":67},[61,2283,2284],{"class":660},"evento",[61,2286,664],{"class":67},[61,2288,2289,2292,2295],{"class":63,"line":176},[61,2290,2291],{"class":67},"  evento.",[61,2293,2294],{"class":653},"preventDefault",[61,2296,2297],{"class":67},"();\n",[61,2299,2300],{"class":63,"line":191},[61,2301,354],{"emptyLinePlaceholder":353},[61,2303,2304,2306,2308,2311,2313],{"class":63,"line":201},[61,2305,724],{"class":71},[61,2307,816],{"class":67},[61,2309,2310],{"class":71},"!",[61,2312,2006],{"class":653},[61,2314,2315],{"class":67},"(campoCPF.value)) {\n",[61,2317,2318,2321,2323,2326,2329,2331],{"class":63,"line":211},[61,2319,2320],{"class":67},"    mensagem.textContent ",[61,2322,93],{"class":71},[61,2324,2325],{"class":96}," \"",[61,2327,2328],{"class":100},"Informe um CPF válido.",[61,2330,97],{"class":96},[61,2332,757],{"class":67},[61,2334,2335,2337],{"class":63,"line":238},[61,2336,751],{"class":71},[61,2338,757],{"class":67},[61,2340,2341],{"class":63,"line":263},[61,2342,762],{"class":67},[61,2344,2345],{"class":63,"line":290},[61,2346,354],{"emptyLinePlaceholder":353},[61,2348,2349,2352,2354,2356,2359,2361],{"class":63,"line":299},[61,2350,2351],{"class":67},"  mensagem.textContent ",[61,2353,93],{"class":71},[61,2355,2325],{"class":96},[61,2357,2358],{"class":100},"CPF válido.",[61,2360,97],{"class":96},[61,2362,757],{"class":67},[61,2364,2365],{"class":63,"line":810},[61,2366,378],{"class":67},[16,2368,2369],{},"Essa validação melhora a experiência no navegador, mas não substitui a validação no servidor. Qualquer código executado no front-end pode ser alterado ou ignorado pelo cliente. O back-end deve repetir a validação antes de salvar ou processar o dado.",[31,2371,1165],{"id":1164},[578,2373,2375],{"id":2374},"validar-cpf-só-com-regex-de-formato","Validar CPF só com regex de formato",[16,2377,2378],{},"Uma expressão como esta:",[52,2380,2382],{"className":335,"code":2381,"language":312,"meta":56,"style":56},"\u002F^\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}$\u002F;\n",[58,2383,2384],{"__ignoreMap":56},[61,2385,2386,2388,2390,2392,2395,2398,2400,2402,2404,2406,2408,2410,2412,2415,2417],{"class":63,"line":64},[61,2387,692],{"class":691},[61,2389,1621],{"class":71},[61,2391,1627],{"class":695},[61,2393,2394],{"class":71},"{3}",[61,2396,2397],{"class":100},"\\.",[61,2399,1627],{"class":695},[61,2401,2394],{"class":71},[61,2403,2397],{"class":100},[61,2405,1627],{"class":695},[61,2407,2394],{"class":71},[61,2409,829],{"class":100},[61,2411,1627],{"class":695},[61,2413,2414],{"class":71},"{2}$",[61,2416,692],{"class":691},[61,2418,757],{"class":67},[16,2420,2421,2422,2425],{},"verifica apenas se o texto tem o formato ",[58,2423,2424],{},"000.000.000-00",". Ela não calcula os dígitos verificadores.",[16,2427,2428,2429,2432],{},"Por exemplo, ",[58,2430,2431],{},"123.456.789-00"," pode estar perfeitamente formatado e ainda assim ser um CPF inválido. Regex pode ajudar a conferir a aparência da entrada, mas não substitui o algoritmo do CPF.",[578,2434,2436],{"id":2435},"esquecer-os-zeros-à-esquerda","Esquecer os zeros à esquerda",[16,2438,2439],{},"CPF é identificador, não número para fazer operações matemáticas comuns. Por isso, trate-o como string.",[16,2441,2442,2443,2446],{},"Se você converter um CPF para ",[58,2444,2445],{},"Number",", um valor com zero inicial pode perder esse zero:",[52,2448,2450],{"className":335,"code":2449,"language":312,"meta":56,"style":56},"const cpf = Number(\"012.345.678-90\");\n",[58,2451,2452],{"__ignoreMap":56},[61,2453,2454,2456,2459,2461,2463,2465,2467,2470,2472],{"class":63,"line":64},[61,2455,2184],{"class":71},[61,2457,2458],{"class":67}," cpf ",[61,2460,93],{"class":71},[61,2462,1716],{"class":653},[61,2464,657],{"class":67},[61,2466,97],{"class":96},[61,2468,2469],{"class":100},"012.345.678-90",[61,2471,97],{"class":96},[61,2473,710],{"class":67},[16,2475,2476,2477,2480],{},"Além disso, números muito grandes não devem ser usados como representação principal de documentos. A função deste artigo converte a entrada para texto com ",[58,2478,2479],{},"String(cpf)"," e remove a formatação antes de calcular.",[16,2482,2483],{},"Na prática, prefira manter o valor vindo do campo HTML como string desde o início.",[578,2485,2487],{"id":2486},"não-normalizar-a-entrada","Não normalizar a entrada",[16,2489,2490],{},"Se o código espera exatamente 11 dígitos, ele pode rejeitar um CPF formatado antes mesmo de fazer o cálculo.",[16,2492,2493],{},"Esta etapa resolve o problema:",[52,2495,2497],{"className":335,"code":2496,"language":312,"meta":56,"style":56},"cpf = String(cpf).replace(\u002F\\D\u002Fg, \"\");\n",[58,2498,2499],{"__ignoreMap":56},[61,2500,2501,2504,2506,2508,2510,2512,2514,2516,2518,2520,2522,2524,2526],{"class":63,"line":64},[61,2502,2503],{"class":67},"cpf ",[61,2505,93],{"class":71},[61,2507,1544],{"class":653},[61,2509,1547],{"class":67},[61,2511,686],{"class":653},[61,2513,657],{"class":67},[61,2515,692],{"class":691},[61,2517,696],{"class":695},[61,2519,692],{"class":691},[61,2521,701],{"class":71},[61,2523,704],{"class":67},[61,2525,707],{"class":96},[61,2527,710],{"class":67},[16,2529,2530],{},"Ela remove pontos, traços, espaços e outros caracteres não numéricos. Depois disso, a função verifica se sobraram exatamente 11 dígitos.",[578,2532,2534],{"id":2533},"validar-apenas-no-navegador","Validar apenas no navegador",[16,2536,2537],{},"A validação no front-end é útil para dar retorno imediato, mas não é uma camada de segurança. Um usuário pode fazer uma requisição diretamente ao servidor sem passar pelo JavaScript da página.",[16,2539,2540],{},"A mesma regra deve existir no back-end, de preferência em uma função centralizada e coberta por testes.",[31,2542,1227],{"id":1226},[578,2544,2546],{"id":2545},"como-saber-se-um-cpf-é-válido","Como saber se um CPF é válido?",[16,2548,2549],{},"Primeiro, remova pontos e traço e confirme que restaram 11 dígitos. Depois, rejeite sequências com todos os dígitos iguais e calcule os dois dígitos verificadores conforme o algoritmo do CPF.",[16,2551,2552,2553,2556],{},"O CPF só será matematicamente válido se os dois dígitos calculados forem iguais aos dois últimos dígitos informados. A função ",[58,2554,2555],{},"validarCPF(cpf)"," apresentada neste artigo executa todas essas etapas.",[16,2558,2559],{},"Isso não significa que o documento esteja ativo, regular ou associado a uma pessoa específica. Significa apenas que ele passa pela validação matemática.",[578,2561,2563],{"id":2562},"como-calcular-o-dígito-verificador-do-cpf","Como calcular o dígito verificador do CPF?",[16,2565,2566],{},"Para o primeiro dígito, multiplique os 9 dígitos base pelos pesos de 10 a 2. Some os resultados e calcule o resto da divisão por 11.",[404,2568,2569,2575],{},[321,2570,2571,2572,26],{},"Se o resto for 0 ou 1, o dígito será ",[58,2573,2574],{},"0",[321,2576,2577,2578,26],{},"Caso contrário, o dígito será ",[58,2579,2580],{},"11 - resto",[16,2582,2583],{},"Para o segundo dígito, faça a mesma operação usando os 10 primeiros dígitos e os pesos de 11 a 2.",[16,2585,2586],{},"Em JavaScript, a parte central do cálculo pode ser escrita assim:",[52,2588,2590],{"className":335,"code":2589,"language":312,"meta":56,"style":56},"const digito = resto \u003C 2 ? 0 : 11 - resto;\n",[58,2591,2592],{"__ignoreMap":56},[61,2593,2594,2596,2599,2601,2603,2605,2607,2609,2611,2613,2615,2617],{"class":63,"line":64},[61,2595,2184],{"class":71},[61,2597,2598],{"class":67}," digito ",[61,2600,93],{"class":71},[61,2602,1747],{"class":67},[61,2604,85],{"class":71},[61,2606,896],{"class":695},[61,2608,1775],{"class":71},[61,2610,779],{"class":695},[61,2612,1780],{"class":71},[61,2614,1587],{"class":695},[61,2616,1729],{"class":71},[61,2618,1787],{"class":67},[578,2620,2622],{"id":2621},"validar-cpf-é-a-mesma-coisa-que-consultar-na-receita-federal","Validar CPF é a mesma coisa que consultar na Receita Federal?",[16,2624,2625],{},"Não. A validação matemática é uma verificação local: o sistema calcula os dígitos e compara o resultado com o CPF informado.",[16,2627,2628],{},"Uma consulta oficial é outra operação. Ela pode verificar informações cadastrais e a situação do CPF em uma base oficial, normalmente por meio de um serviço autorizado ou dos canais disponibilizados pela Receita Federal.",[16,2630,2631],{},"Portanto, um CPF pode passar pelo algoritmo e ainda não estar regular, não existir no cadastro consultado ou não pertencer à pessoa que o informou. O código JavaScript não confirma identidade nem situação cadastral.",[578,2633,2635],{"id":2634},"dá-para-gerar-um-cpf-válido-para-testes","Dá para gerar um CPF válido para testes?",[16,2637,2638,2639,2644],{},"Sim. Para testar máscaras, formulários e APIs, você pode usar números que passam pela validação matemática sem usar dados reais. Se você precisa de números de CPF válidos só para testar formulários, ",[20,2640,2643],{"href":2641,"rel":2642},"https:\u002F\u002Fcodigoaoponto.com\u002Fferramentas\u002Fgerador-de-cpf",[24],"nosso gerador de CPF"," resolve isso rapidinho.",[16,2646,2647],{},"Use dados de teste de forma controlada e deixe claro, no ambiente da equipe, que eles são fictícios. Também evite colocar documentos reais em exemplos públicos, arquivos de teste ou repositórios.",[578,2649,2651],{"id":2650},"a-função-valida-se-o-cpf-pertence-ao-usuário","A função valida se o CPF pertence ao usuário?",[16,2653,2654],{},"Não. Ela verifica somente o formato normalizado, a quantidade de dígitos, a regra dos dígitos verificadores e a rejeição de sequências repetidas.",[16,2656,2657],{},"Para confirmar titularidade, seria necessária uma etapa diferente, com uma fonte oficial ou um fluxo de verificação apropriado. A validação local não substitui esse processo.",[31,2659,2661],{"id":2660},"próximos-passos","Próximos passos",[16,2663,2664,2665,2667],{},"Agora você já tem o algoritmo do CPF e uma função ",[58,2666,2555],{}," pronta para adaptar ao seu projeto. Coloque a validação no front-end para orientar o usuário e repita a regra no back-end antes de persistir ou aceitar o cadastro.",[16,2669,2670,2671,2675],{},"Se quiser conferir valores sem escrever código, acesse ",[20,2672,2674],{"href":2165,"rel":2673},[24],"o nosso verificador de CPF online",". Depois, vale transformar os exemplos deste artigo em testes automatizados para cobrir entradas formatadas, CPFs inválidos e documentos com zeros à esquerda.",[478,2677,2678],{},"html pre.shiki code .s0Tla, html code.shiki .s0Tla{--shiki-default:#FF79C6}html pre.shiki code .sAOxA, html code.shiki .sAOxA{--shiki-default:#50FA7B}html pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .sGEwX, html code.shiki .sGEwX{--shiki-default:#FFB86C;--shiki-default-font-style:italic}html pre.shiki code .shSDL, html code.shiki .shSDL{--shiki-default:#6272A4}html pre.shiki code .s-doY, html code.shiki .s-doY{--shiki-default:#FF5555}html pre.shiki code .sIQBb, html code.shiki .sIQBb{--shiki-default:#BD93F9}html pre.shiki code .seVfx, html code.shiki .seVfx{--shiki-default:#E9F284}html pre.shiki code .smvxG, html code.shiki .smvxG{--shiki-default:#FFB86C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}",{"title":56,"searchDepth":82,"depth":82,"links":2680},[2681,2685,2688,2694,2701],{"id":1351,"depth":82,"text":1352,"children":2682},[2683,2684],{"id":1372,"depth":108,"text":1373},{"id":1437,"depth":108,"text":1438},{"id":636,"depth":82,"text":637,"children":2686},[2687],{"id":2170,"depth":108,"text":2171},{"id":1164,"depth":82,"text":1165,"children":2689},[2690,2691,2692,2693],{"id":2374,"depth":108,"text":2375},{"id":2435,"depth":108,"text":2436},{"id":2486,"depth":108,"text":2487},{"id":2533,"depth":108,"text":2534},{"id":1226,"depth":82,"text":1227,"children":2695},[2696,2697,2698,2699,2700],{"id":2545,"depth":108,"text":2546},{"id":2562,"depth":108,"text":2563},{"id":2621,"depth":108,"text":2622},{"id":2634,"depth":108,"text":2635},{"id":2650,"depth":108,"text":2651},{"id":2660,"depth":82,"text":2661},[312,1320],"Aprenda como validar um CPF com JavaScript puro, calcular os dígitos verificadores, tratar formatação e rejeitar sequências inválidas em formulários.","how-to-validate-cpf-with-javascript",{},"\u002Fblog\u002Fcomo-validar-cpf-com-javascript","como-validar-cpf-com-javascript",{"title":1335,"description":2703},{"loc":2706,"lastmod":1329},"blog\u002Fcomo-validar-cpf-com-javascript",1197,"7Wua_lEutUOlPT1fzwogiuAkC9M32KKgCh-CkJJPURA",1791122448680]