JavaScript CPF generator [closed]

3

I made a CPF generator in JavaScript, and was wondering if my code is good or what I can improve on it?

Function that will be called by event onsubmit

function gerarCpf() {
var cpf = document.getElementById("cpf");

var num1 = aleatorio().toString();
var num2 = aleatorio().toString();
var num3 = aleatorio().toString();

var dig1 = digPri(num1,num2,num3);
var dig2 = digSeg(num1,num2,num3,dig1);
cpf.value = num1+"."+num2+"."+num3+"-"+dig1+""+dig2;}

Function that calculates the first check digit

function digPri(n1,n2,n3) {
var nn1 = n1.split("");
var nn2 = n2.split("");
var nn3 = n3.split("");
var nums = nn1.concat(nn2,nn3);

var x = 0;
var j = 0;
for (var i=10;i>=2;i--) {
    x += parseInt(nums[j++]) * i;
}
var y = x % 11;
if (y < 2) {
    return 0;
} else {
    return 11-y;
}}

Function that calculates the second check digit

function digSeg(n1,n2,n3,n4) {
var nn1 = n1.split("");
var nn2 = n2.split("");
var nn3 = n3.split("");
var nums = nn1.concat(nn2,nn3);
nums[9] = n4;
var x = 0;
var j = 0;
for (var i=11;i>=2;i--) {
    x += parseInt(nums[j++]) * i;
}
var y = x % 11;
if (y < 2) {
    return 0;
} else {
    return 11-y;
}}

Function that returns random number with 3 fixed digits

function aleatorio() {
var aleat = Math.floor(Math.random() * 999);
if (aleat < 100) {
    if (aleat < 10) {
        return "00"+aleat;
    } else {
        return "0"+aleat;
    }
} else {
    return aleat;
}}
    
asked by anonymous 08.10.2017 / 21:09

1 answer

4

The biggest improvement to make in your code is to transform the two functions of generating the verifier digits into one, since they are almost equal.

It also has several other writing and structuring details that can be improved.

It could look like this:

//obtem o elemento apenas uma vez no inicio em vez de todas as vezes que gera o cpf
const cpf = document.getElementById("cpf"); 

function gerarCpf() {
  const num1 = aleatorio(); //aleatorio já devolve string, logo não precisa de toString
  const num2 = aleatorio();
  const num3 = aleatorio();

  const dig1 = dig(num1, num2, num3); //agora só uma função dig
  const dig2 = dig(num1, num2, num3, dig1); //mesma função dig aqui

  //aqui com interpolação de strings fica bem mais legivel
  cpf.value = '${num1}.${num2}.${num3}-${dig1}${dig2}';
}

//o quarto parametro(n4) só será recebido para o segundo digito
function dig(n1, n2, n3, n4) { 
  
  //as concatenações todas juntas uma vez que são curtas e legíveis
  let nums = n1.split("").concat(n2.split(""), n3.split(""));
  
  if (n4){ //se for o segundo digito coloca o n4 no sitio certo
    nums[9] = n4;
  }
  
  let x = 0;
   
  //o j é também iniciado e incrementado no for para aproveitar a própria sintaxe dele
  //o i tem inicios diferentes consoante é 1º ou 2º digito verificador
  for (let i = (n4 ? 11:10), j = 0; i >= 2; i--, j++) {
    x += parseInt(nums[j]) * i;
  }
  
  const y = x % 11;
  //ternário aqui pois ambos os retornos são simples e continua legivel
  return y < 2 ? 0 : 11 - y; 
}

function aleatorio() {
  const aleat = Math.floor(Math.random() * 999);
 //o preenchimento dos zeros à esquerda é mais facil com a função padStart da string
  return ("" + aleat).padStart(3, '0'); 
}

gerarCpf();
<input type="text" id="cpf">

Note also that I have chosen to transform all statements into let or const which are the most modern and correct ways of doing today.

Code Golf

For the sake of curiosity and grace, and in an attempt to do a little Code Golf in your code to make it super short level of writing (though not very readable) could do so:

const cpf = document.getElementById("cpf"); 

function gerarCpf() {
  const n1 = aleatorio(), n2 = aleatorio(), n3 = aleatorio(), d1 = dig(n1, n2, n3);
  cpf.value = '${n1}.${n2}.${n3}-${d1}${dig(n1, n2, n3, d1)}';
}

function dig(n1, n2, n3, n4) { 
  let nums = n1.split("").concat(n2.split(""), n3.split("")), x = 0;    
  if (n4) nums[9] = n4;
  for (let i = (n4 ? 11:10), j = 0; i >= 2; i--, j++) x += parseInt(nums[j]) * i;
  return (y = x % 11) < 2 ? 0 : 11 - (y = x % 11); 
}

function aleatorio() {
  return ("" + Math.floor(Math.random() * 999)).padStart(3, '0'); 
}

gerarCpf();
<input type="text" id="cpf">
    
08.10.2017 / 21:59