Skip to content

Instantly share code, notes, and snippets.

@fiuzagr
Last active October 7, 2024 18:28
Show Gist options
  • Save fiuzagr/a267fcc66388e0c43912364f0df042d6 to your computer and use it in GitHub Desktop.
Save fiuzagr/a267fcc66388e0c43912364f0df042d6 to your computer and use it in GitHub Desktop.
Gerador/Validador de CPF funcional
const digitMod = (value, len) => {
const mod = len - Math.round(value - Math.floor(value / len) * len);
return mod >= 10 ? 0 : mod;
};
const mapValuesWithDigitModByKey = (_key, _len) => (value, key) =>
_key === key ? digitMod(value, _len) : value;
const reduceDigitsByKey = _key => (digits, value, key) => {
if (key > _key) {
digits[_key] = digits[_key] + value * (key + (_key === 0 ? 1 : 0));
digits[key] = value;
}
return digits;
};
const genArrayDigits = len => new Array(len).fill(0);
const genRandomArrayDigits = len =>
genArrayDigits(len).map(() => Math.round(Math.random() * 9));
const reduceArrayDigits = (digits, verifyDigits) =>
verifyDigits.length
? reduceArrayDigits(
digits
.reduce(
reduceDigitsByKey(verifyDigits.length - 1),
genArrayDigits(verifyDigits.length)
)
.map(mapValuesWithDigitModByKey(verifyDigits.length - 1, digits.length)),
verifyDigits.slice(1)
)
: digits;
const calculateDigits = (digits, verifyDigits) =>
reduceArrayDigits(digits.concat(verifyDigits).reverse(), verifyDigits).reverse();
const generateCpf = () =>
calculateDigits(genRandomArrayDigits(9), genArrayDigits(2)).join('');
const validateCpf = cpf =>
calculateDigits(cpf.split('').slice(0, -2), genArrayDigits(2)).join('') === cpf;
// use:
//document.getElementById('generate').innerText = generateCpf();
//document.getElementById('validate').innerText = validateCpf('75314746700');
// Implements your own verified digits:
//const generateAnotherVerifiedDigits = () =>
// calculateDigits(genRandomArrayDigits(10), genArrayDigits(3)).join('');
//const validateAnotherVerifiedDigits = digits =>
// calculateDigits(digits.split('').slice(0, -3), genArrayDigits(3)).join('') === digits;
@fiuzagr
Copy link
Author

fiuzagr commented Oct 7, 2024

function getVerifyingDigit(arr: number[]) {
  const reduced = arr.reduce(
    (sum, digit, index) => sum + digit * (arr.length - index + 1),
    0,
  );

  return ((reduced * 10) % 11) % 10;
}

function verifyRepeatedDigits(value: string) {
  return !!/(\d)\1{10}/.exec(value);
}

export function validateCpf(value: string) {
  value = value.replace(/\D+/g, "");

  if (value.length !== 11 || verifyRepeatedDigits(value)) {
    return false;
  }

  const digits = value.split("").map((el) => +el);

  return (
    getVerifyingDigit(digits.slice(0, 9)) === digits[9] &&
    getVerifyingDigit(digits.slice(0, 10)) === digits[10]
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment