Java tutorial
/* * Copyright 2008 JRimum Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by * applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS * OF ANY KIND, either express or implied. See the License for the specific * language governing permissions and limitations under the License. * * Created at: 30/03/2008 - 18:51:09 * * ================================================================================ * * Direitos autorais 2008 JRimum Project * * Licenciado sob a Licena Apache, Verso 2.0 ("LICENA"); voc no pode usar * esse arquivo exceto em conformidade com a esta LICENA. Voc pode obter uma * cpia desta LICENA em http://www.apache.org/licenses/LICENSE-2.0 A menos que * haja exigncia legal ou acordo por escrito, a distribuio de software sob * esta LICENA se dar COMO EST??, SEM GARANTIAS OU CONDIES DE QUALQUER * TIPO, sejam expressas ou tcitas. Veja a LICENA para a redao especfica a * reger permisses e limitaes sob esta LICENA. * * Criado em: 30/03/2008 - 18:51:09 * */ package br.com.nordestefomento.jrimum.vallia.digitoverificador; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import br.com.nordestefomento.jrimum.utilix.Filler; /** * <p> * O clculo do dgito verificador do CPF realizado em duas etapas e * auxiliado pela rotina de mdulo 11. * </p> * <p> * Abaixo demonstrado como esse clculo feito: * </p> * <h3>Exemplo para um nmero hipottico 222.333.666-XX:</h3> * <p> * Primeiramente obtm-se um nmero R, calculado atravs da rotina de mdulo 11, * a partir dos nove primeiros nmeros do CPF, nesse caso 222333666. <br /> * Para obter o primeiro dgito verificador deve-se seguir a seguinte lgica: <br /> * <br /> * Se o nmero R for menor que 2, o dgito ter valor 0 (zero); seno, ser a * subtrao do valor do mdulo (11) menos o valor do nmero R, ou seja, * <code>DV = 11 - R</code>. * </p> * <p> * Para obter o segundo dgito verificador da mesma forma do primeiro, porm * deve ser calculado a partir dos dez primeiros nmeros do CPF, ou seja, * 222333666 + primeiro dgito. * </p> * <p> * Obs.: Os limites mnimos e mximos do mdulo 11 para o clculo do primeiro e * do segundo dgito verificador so 2 - 10 e 2 e 11, respectivamente. * </p> * * @see Modulo * * * @author <a href="http://gilmatryx.googlepages.com/">Gilmar P.S.L</a> * @author Misael Barreto * @author Rmulo Augusto * @author <a href="http://www.nordeste-fomento.com.br">Nordeste Fomento * Mercantil</a> * * @since 0.2 * * @version 0.2 */ public class CPFDV extends AbstractDigitoVerificador { /** * */ private static final long serialVersionUID = 2059692008894172695L; /** * <p> * Liminte mnimo do para clculo no mdulo 11. *</p> */ private static final int LIMITE_MINIMO = 2; /** * <p> * Expresso regular para validao dos nove primeiros nmeros do CPF sem * formatao: <tt>"#########"</tt>. * </p> */ private static final String REGEX_CPF_DV = "\\d{9}"; /** * <p> * Expresso regular para validao dos nove primeiros nmeros do CPF * formatado: <tt>"###.###.###"</tt>. * </p> */ private static final String REGEX_CPF_DV_FORMATTED = "\\d{3}\\.\\d{3}\\.\\d{3}"; /** * @see br.com.nordestefomento.jrimum.vallia.digitoverificador.AbstractDigitoVerificador#calcule(long) * @since 0.2 */ @Override public int calcule(long numero) { return calcule(Filler.ZERO_LEFT.fill(String.valueOf(numero), 9)); } /** * @see br.com.nordestefomento.jrimum.vallia.digitoverificador.AbstractDigitoVerificador#calcule(java.lang.String) * @since 0.2 */ @Override public int calcule(String numero) throws IllegalArgumentException { int dv1 = 0; int dv2 = 0; boolean isFormatoValido = false; validacao: { if (StringUtils.isNotBlank(numero)) { isFormatoValido = (Pattern.matches(REGEX_CPF_DV, numero) || Pattern.matches(REGEX_CPF_DV_FORMATTED, numero)); if (isFormatoValido) { numero = StringUtils.replaceChars(numero, ".", ""); dv1 = calcule(numero, 10); dv2 = calcule(numero + dv1, 11); break validacao; } } throw new IllegalArgumentException("O CPF [ " + numero + " ] deve conter apenas nmeros, sendo eles no formato ###.###.### ou ######### !"); } return Integer.parseInt(dv1 + "" + dv2); } /** * <p> * Mtodo auxiliar para o clculo do dgito verificador. * </p> * <p> * Calcula os dgitos separadamente. * </p> * * @param numero * - nmero a partir do qual ser extrado o dgito verificador. * @param limiteMaximoDoModulo * - limite mximo do mdulo utilizado, no caso, mdulo 11. * @return um nmero que faz parte de um dgito verificador. * @throws IllegalArgumentException * caso o nmero no esteja no formatador desejvel. * @since 0.2 */ private int calcule(String numero, int limiteMaximoDoModulo) throws IllegalArgumentException { int dv = 0; int resto = 0; resto = Modulo.calculeMod11(numero, LIMITE_MINIMO, limiteMaximoDoModulo); if (resto >= 2) { dv = TipoDeModulo.MODULO11.valor() - resto; } return dv; } }