package br.com.concretesolutions.canarinho.validator; import android.text.Editable; import br.com.concretesolutions.canarinho.DigitoPara; import br.com.concretesolutions.canarinho.formatador.Formatador; /** * Implementação de @{link Validador} para CPF * * @see Validador */ public final class ValidadorCPF implements Validador { private static final DigitoPara DIGITO_PARA_CPF = new DigitoPara.Builder() .comMultiplicadoresDeAte(2, 11) .complementarAoModulo() .trocandoPorSeEncontrar("0", 10, 11) .build(); // No instance creation private ValidadorCPF() { } static ValidadorCPF getInstance() { return SingletonHolder.INSTANCE; } @Override public boolean ehValido(String value) { if (value == null || value.length() < 11) { return false; } final String desformatado = Formatador.Padroes.PADRAO_SOMENTE_NUMEROS.matcher(value).replaceAll(""); if (desformatado.length() != 11) { return false; } if (estaNaListaNegra(desformatado)) { return false; } final String cpfSemDigito = desformatado.substring(0, desformatado.length() - 2); final String digitos = desformatado.substring(desformatado.length() - 2); final String dig1 = DIGITO_PARA_CPF.calcula(cpfSemDigito); final String dig2 = DIGITO_PARA_CPF.calcula(cpfSemDigito + dig1); return (dig1 + dig2).equals(digitos); } @Override public ResultadoParcial ehValido(Editable valor, ResultadoParcial resultadoParcial) { if (resultadoParcial == null || valor == null) { throw new IllegalArgumentException("Valores não podem ser nulos"); } final String desformatado = Formatador.Padroes.PADRAO_SOMENTE_NUMEROS.matcher(valor).replaceAll(""); if (!ehValido(desformatado)) { return resultadoParcial .parcialmenteValido(desformatado.length() < 11) .mensagem("CPF inválido") .totalmenteValido(false); } return resultadoParcial .parcialmenteValido(true) .totalmenteValido(true); } // De acordo ao cálculo dos digitos verificadores, os CPFs abaixo são válidos, entretanto os mesmo // são considerados inválidos pela Receita Federal // 00000000000, 11111111111, 22222222222, 33333333333, 44444444444, 55555555555, // 66666666666, 77777777777, 88888888888, 99999999999, 12345678909 private boolean estaNaListaNegra(String valor) { boolean igual = true; for (int i = 1; i < 11 && igual; i++) { if (valor.charAt(i) != valor.charAt(0)) { igual = false; } } return igual || valor.equals("12345678909"); } private static class SingletonHolder { private static final ValidadorCPF INSTANCE = new ValidadorCPF(); } }