// Porte direto dos geradores Go: // cpf_generator/main.go -> generateCPF // cnpj_generator/cnpj/generate.go -> generateCNPJ / generateCNPJAlpha // // Diferença deliberada: aqui o aleatório vem de crypto.getRandomValues em vez // de math/rand. Os dígitos verificadores seguem exatamente as mesmas contas. const ALPHA_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const CNPJ_P1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; const CNPJ_P2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; // Inteiro uniforme em [0, max) sem o viés do módulo. function randomInt(max) { const limit = Math.floor(0xffffffff / max) * max; const buf = new Uint32Array(1); let v; do { crypto.getRandomValues(buf); v = buf[0]; } while (v >= limit); return v % max; } export function generateCPF() { const digits = new Array(11); for (let i = 0; i < 9; i++) { digits[i] = randomInt(10); } let sum = 0; for (let i = 0; i < 9; i++) { sum += digits[i] * (10 - i); } let rem = sum % 11; digits[9] = rem < 2 ? 0 : 11 - rem; sum = 0; for (let i = 0; i < 10; i++) { sum += digits[i] * (11 - i); } rem = sum % 11; digits[10] = rem < 2 ? 0 : 11 - rem; return digits.join(""); } export function formatCPF(cpf) { if (cpf.length !== 11) return cpf; return `${cpf.slice(0, 3)}.${cpf.slice(3, 6)}.${cpf.slice(6, 9)}-${cpf.slice(9)}`; } // Peso posicional do caractere: dígitos valem 0-9, letras valem código ASCII - 48 // (A = 17), conforme a regra do CNPJ alfanumérico. function alphaValue(ch) { return ch.charCodeAt(0) - 48; } function computeDV(s, table) { let total = 0; for (let i = 0; i < table.length; i++) { total += alphaValue(s[i]) * table[i]; } const r = total % 11; return r >= 2 ? 11 - r : 0; } function isRepetitive(s) { if (s.length === 0) return false; for (let i = 1; i < s.length; i++) { if (s[i] !== s[0]) return false; } return true; } function generateCNPJBase(alpha) { for (;;) { let s = ""; for (let i = 0; i < 12; i++) { s += alpha ? ALPHA_CHARS[randomInt(ALPHA_CHARS.length)] : String(randomInt(10)); } if (isRepetitive(s)) continue; const dv1 = computeDV(s, CNPJ_P1); const dv2 = computeDV(s + dv1, CNPJ_P2); return `${s}${dv1}${dv2}`; } } export function generateCNPJ() { return generateCNPJBase(false); } export function generateCNPJAlpha() { return generateCNPJBase(true); } export function formatCNPJ(cnpj) { if (cnpj.length !== 14) return cnpj; return `${cnpj.slice(0, 2)}.${cnpj.slice(2, 5)}.${cnpj.slice(5, 8)}/${cnpj.slice(8, 12)}-${cnpj.slice(12)}`; }