Skip to content

Instantly share code, notes, and snippets.

@matheustp
Last active July 15, 2017 21:15
Show Gist options
  • Save matheustp/d0f4a30e97195202d797eb14c4a762ff to your computer and use it in GitHub Desktop.
Save matheustp/d0f4a30e97195202d797eb14c4a762ff to your computer and use it in GitHub Desktop.
CPF Refatorado
const getDigit = ( cpf ) => cpf.slice( 9 )
const mod11 = ( num ) => num % 11
const generateArrayOfLength = ( length ) => Array.from( { length }, ( v, k ) => k )
const invalidCpfs = generateArrayOfLength( 10 ).map( val => `${ val }`.repeat( 11 ) )
const isEqual = ( val1 ) => ( val2 ) => val1 === val2
const isIn = ( list ) => ( num ) => list.findIndex( isEqual( num ) ) >= 0
const isInInvalidCpf = isIn( invalidCpfs )
const NOT = ( val ) => !val
const getCpfAsArrayWithoutDigit = ( cpf ) => cpf.split( '' ).slice( 0, 9 )
const calcSumDigit = ( multiplier, digit, sum ) => sum + ( digit * multiplier )
const calculateSums = ( multiplier ) => ( [ sum2, sum1 ] , currentNum ) =>
[ calcSumDigit( multiplier--, currentNum, sum2 ), calcSumDigit( multiplier, currentNum, sum1 ) ]
/*
O calculo de calculateDigit foi alterado, baseando-se no item 4:
4) Caso o valor do resto da divisão seja menor que 2,
esse valor passa automaticamente a ser zero,
caso contrário é necessário subtrair o valor obtido
de 11 para se obter o dígito verificador.
Fonte: http://www.geradorcpf.com/algoritmo_do_cpf.htm
*/
const calculateDigit = ( num ) => ( mod11( num ) < 2 ? 0 : 11 - mod11( num ) )
const concatDigits = ( firstDigit, secondDigit ) =>
(firstDigit !== 0)
? ( firstDigit * 10 ) + secondDigit + ''
: '0' + secondDigit
const generateDigit = ( previousNum, currentNum ) =>
( previousNum === null )
? calculateDigit( currentNum )
: concatDigits( previousNum, calculateDigit( ( previousNum * 2) + currentNum ) )
const isCpfRight = ( cpf ) =>
getCpfAsArrayWithoutDigit( cpf )
.reduce( calculateSums( 11 ), [ 0, 0 ] )
.reverse().reduce( generateDigit, null ) === getDigit( cpf )
const validate = ( cpf ) => ( NOT( isInInvalidCpf( cpf ) ) && isCpfRight( cpf ) )
const CPFS = [
'04998264931', '03506838326',
'03506838321', '22222222222',
'00000000000', '04864713901'
]
CPFS.forEach( ( cpf ) => console.log( `${ cpf }: ${ validate( cpf ) }` ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment