Guest User

lavieri

a guest
Mar 3rd, 2009
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.61 KB | None | 0 0
  1. package org.lavieri.util.brazil.register;
  2.  
  3. import javax.persistence.Transient;
  4.  
  5. /**
  6.  * Prove uma valida��o generica de digitos verificadores de acordo com os parametros
  7.  * especificados.
  8.  * <BR>
  9.  * <BR>Serve como utilit�rio para classes que que necessitem de valida��o de digitos
  10.  * verificadres, como CPF, CNPJ, Inscri��o Estadual, ou qualquer uma outra, que siga os
  11.  * padr�es aqui estipulado.
  12.  * <BR>
  13.  * <BR>Exemplo de uso:
  14.  * A classe cpf pode implementar sua valida��o da seguinte forma:<tt>
  15.  * <BR>/**
  16.  * <BR>&nbsp;* Pesos para o calculor de dos digitos verificadores do CPF.
  17.  * <BR>&nbsp;*</tt><tt>/
  18.  * <BR>private static final int[][] COEFICIENTS =
  19.  * <BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
  20.  * <BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
  21.  * {10,9,8,7,6,5,4,3,2}, //pesos para o 1� digito verificador
  22.  * <BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
  23.  * {11,10,9,8,7,6,5,4,3} //pesos para o 2� digito verificador
  24.  * <BR> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
  25.  * <BR>/**
  26.  * <BR>&nbsp;* N�mero de digitos de um CPF (excluindo-se os digitos verificadores)
  27.  * <BR>&nbsp;*</tt><tt>/
  28.  * <BR>private static final int BASE_LENGTH = 9;
  29.  * <BR>/**
  30.  * <BR>&nbsp;* Fator de divis�o, usado no calculo dos digitos verificadores.
  31.  * <BR>&nbsp;*</tt><tt>/
  32.  * <BR>private static final int FACTOR = 11; //fator de divis�o para calculo dos digitos
  33.  * <BR>
  34.  * <BR>/**
  35.  * <BR>&nbsp;* Verifica��o se este CPF � valido, null significa que o teste ainda n�o foi
  36.  * <BR>&nbsp;* realizado, so � verificar uma vez, apois a primeira chamada de isValid()
  37.  * <BR>&nbsp;* @see isValid()
  38.  * <BR>&nbsp;*</tt><tt>/
  39.  * <BR>@{@link Transient} private Boolean valid = null;
  40.  * <BR>/**
  41.  * <BR>&nbsp;* String contendo o valor deste CPF
  42.  * <BR>&nbsp;*</tt><tt>/
  43.  * <BR>private String cpf;
  44.  * <BR>
  45.  * <BR>//...
  46.  * <BR>// outros m�todos
  47.  * <BR>//...
  48.  * <BR>
  49.  * <BR>public boolean isValid() {
  50.  * <BR>&nbsp; &nbsp; if (valid == null)
  51.  * <BR>&nbsp; &nbsp; &nbsp; &nbsp; valid = {@link VerifierDigits}.isValid(this.cpf,
  52.  * <i>BASE_LENGTH</i>, <i>FACTOR</i>, <i>COEFICIENTS</i>);
  53.  * <BR>&nbsp; &nbsp; return valid;
  54.  * <BR>}</tt>
  55.  * <BR>
  56.  * <BR>Last Revision: 01/12/2009
  57.  * @author Tomaz Lavieri
  58.  * @version 1.0
  59.  * @since 01/12/09
  60.  */
  61. public class VerifierDigits {
  62.     /**
  63.      * Mensagem de erro, quando o n�mero de digitos a checar � diferente da soma do
  64.      * n�mero de digitos basicos mais o n�mero de digitos validadores.
  65.      */
  66.     private final static String ERROR = "The digits to check \"%s\" length (%s) "+
  67.                 "must be equals to: base length (%s) + digits of verifier digitis (%s)";
  68.    
  69.     /**
  70.      * Verifica se a sequencia de digitos <tt>digitsToCheck</tt>, que tem dimens�o
  71.      * basica <tt>baseLength</tt> (o restante � digitos verificadores), onde cada digito
  72.      * verificador utiliza o <tt>factor</tt> de divis�o e os pesos enviado na array de
  73.      * {@link DigitsSequence}[] <tt>coeficients</tt>
  74.      * @param digitsToCheck sequencia de digitos a ser validada.
  75.      * @param baseLength dimens�o basica da sequencia de digitos. Por exemplo o CPF tem
  76.      *          dimens�o basica = 9 os outros 2 s�o digitos verificadores.
  77.      * @param factor o divisor do teste dos digitos. Por exemplo o CPF usa divisor 11
  78.      * @param coeficients uma array de DigitsSequence com os pesos para cada digito
  79.      *          verificador. Por exemplo para o CNPJ a array �<tt>
  80.      *        <BR>coeficients = {@link DigitsSequence}[2];
  81.      *      <BR>coeficients[0] = new {@link IntegerDigitsSequence}({5,4,3,2,9,8,7,6,5,4,3,2});
  82.      *        <BR>coeficients[1] = new {@link StringDigitsSequence}("6543298765432");
  83.      *          </tt>
  84.      * @return <tt>true</tt> caso a sequencia de digitos contenha os verificadores
  85.      *          corretos, e <tt>false</tt> caso contrario.
  86.      */
  87.     public static boolean isValid(DigitsSequence digitsToCheck,int baseLength, int factor,
  88.             DigitsSequence ... coeficients ) throws IllegalArgumentException {
  89.         if (digitsToCheck.length() != baseLength + coeficients.length)
  90.             throwIllegalArgumentException(digitsToCheck,baseLength,coeficients.length);
  91.         boolean result = false;
  92.         boolean needMoreTest = coeficients.length > 0;
  93.         int coeficientsCursor = 0;
  94.         while(needMoreTest) {
  95.             int sum = 0;
  96.             int currentCoeficientsSize = baseLength + coeficientsCursor;
  97.             for (int i = 0; i < currentCoeficientsSize; i++ ) {
  98.                 sum +=  digitsToCheck.getNumberAt(i) *
  99.                         coeficients[coeficientsCursor].getNumberAt(i);
  100.             }
  101.             int correctDigit = (factor - sum%factor >= 10) ? 0 : factor - sum%factor;
  102.             result = correctDigit == digitsToCheck.getNumberAt(currentCoeficientsSize);
  103.             needMoreTest = (++coeficientsCursor < coeficients.length && result == true);
  104.         }
  105.         return result;
  106.     }
  107.     public static String getValidDigits(DigitsSequence digitsToCheck,int baseLength,
  108.             int factor, DigitsSequence ... coeficients )throws IllegalArgumentException {
  109.         if (digitsToCheck.length() != baseLength + coeficients.length)
  110.             throwIllegalArgumentException(digitsToCheck,baseLength,coeficients.length);
  111.         String result = "";
  112.         int[] sum = new int[coeficients.length];
  113.         for (int i = 0; i < baseLength; i++)
  114.             for (int j = 0; j < sum.length; j++)
  115.                 sum[j] += digitsToCheck.getNumberAt(i) * coeficients[j].getNumberAt(i);
  116.         int[] digit = new int[coeficients.length];
  117.         boolean hasMore = true;
  118.         int cursor = 0;
  119.         while (hasMore) {
  120.             digit[cursor] = (factor - (sum[cursor]%factor) >= 10) ? 0 :
  121.                 factor - (sum[cursor]%factor);
  122.             result += digit[cursor++];
  123.             hasMore = (cursor + baseLength < digitsToCheck.length());
  124.             if (hasMore)
  125.                 for (int j = cursor ; j < coeficients.length ; j++)
  126.                     sum[j] += digit[cursor-1] * //digito recem calculado  
  127.                         coeficients[j].getNumberAt(baseLength + cursor -1); //peso
  128.         }
  129.         return result;
  130.     }
  131.    
  132.     /**
  133.      * Verifica se a sequencia de digitos <tt>digitsToCheck</tt>, que tem dimens�o
  134.      * basica <tt>baseLength</tt> (o restante � digitos verificadores), onde cada digito
  135.      * verificador utiliza o <tt>factor</tt> de divis�o e os pesos enviado na array de
  136.      * {@link String}[] <tt>coeficients</tt>
  137.      * @param digitsToCheck sequencia de digitos a ser validada.
  138.      * @param baseLength dimens�o basica da sequencia de digitos. Por exemplo o CPF tem
  139.      *          dimens�o basica = 9 os outros 2 s�o digitos verificadores.
  140.      * @param factor o divisor do teste dos digitos. Por exemplo o CPF usa divisor 11
  141.      * @param coeficients uma array de String com os pesos para cada digito
  142.      *          verificador, onde cada peso � um digito entre 0 e 9.
  143.      *        <BR>Por exemplo para o CNPJ a array �<tt>
  144.      *        <BR>coeficients = {@link String}[2];
  145.      *      <BR>coeficients[0] = "543298765432";
  146.      *        <BR>coeficients[1] = "6543298765432";</tt>
  147.      * @return <tt>true</tt> caso a sequencia de digitos contenha os verificadores
  148.      *          corretos, e <tt>false</tt> caso contrario.
  149.      */
  150.     public static boolean isValid(String digitsToCheck,int baseLength, int factor,
  151.             String ... coeficients ) {
  152.         StringDigitsSequence siDigitsToCheck = new StringDigitsSequence(digitsToCheck);
  153.         if (siDigitsToCheck.length() != baseLength + coeficients.length)
  154.             throwIllegalArgumentException(siDigitsToCheck,baseLength,coeficients.length);
  155.         StringDigitsSequence[] coefcientsStrSequence =
  156.             new StringDigitsSequence[coeficients.length];
  157.         for(int i = 0; i<coeficients.length; i++) {
  158.             coefcientsStrSequence[i] = new StringDigitsSequence(coeficients[i]);
  159.         }
  160.         return isValid(siDigitsToCheck, baseLength, factor, coefcientsStrSequence);
  161.     }
  162.     /**
  163.      * Verifica se a sequencia de digitos <tt>digitsToCheck</tt>, que tem dimens�o
  164.      * basica <tt>baseLength</tt> (o restante � digitos verificadores), onde cada digito
  165.      * verificador utiliza o <tt>factor</tt> de divis�o e os pesos enviado na array de
  166.      * <tt>int[][] coeficients</tt>
  167.      * @param digitsToCheck sequencia de digitos a ser validada.
  168.      * @param baseLength dimens�o basica da sequencia de digitos. Por exemplo o CPF tem
  169.      *          dimens�o basica = 9 os outros 2 s�o digitos verificadores.
  170.      * @param factor o divisor do teste dos digitos. Por exemplo o CPF usa divisor 11
  171.      * @param coeficients uma array de int com os pesos para cada digito
  172.      *          verificador. Por exemplo para o CPF a array �<tt>
  173.      *        <BR>coeficients = int[2];
  174.      *      <BR>coeficients[0] = {10, 9,8,7,6,5,4,3,2};
  175.      *        <BR>coeficients[1] = {11,10,9,8,7,6,5,4,3,0};</tt>
  176.      * @return <tt>true</tt> caso a sequencia de digitos contenha os verificadores
  177.      *          corretos, e <tt>false</tt> caso contrario.
  178.      */
  179.     public static boolean isValid(String digitsToCheck,int baseLength, int factor,
  180.             int[] ... coeficients ) {
  181.         StringDigitsSequence siDigitsToCheck = new StringDigitsSequence(digitsToCheck);
  182.         if (siDigitsToCheck.length() != baseLength + coeficients.length)
  183.             throwIllegalArgumentException(siDigitsToCheck,baseLength,coeficients.length);
  184.         IntegerDigitsSequence[] coefcientsIntSequence =new IntegerDigitsSequence[coeficients.length];
  185.         for(int i = 0; i<coeficients.length; i++) {
  186.             coefcientsIntSequence[i] = new IntegerDigitsSequence(coeficients[i]);
  187.         }
  188.         return isValid(siDigitsToCheck, baseLength, factor, coefcientsIntSequence);
  189.     }
  190.     /**
  191.      * Lan�a uma exce��o de erro, com mensagem especifica do erro.
  192.      * @param siDigitsToCheck
  193.      * @param baseLength
  194.      * @param numberOfVerifierDigits
  195.      * @throws IllegalArgumentException
  196.      */
  197.     private static void throwIllegalArgumentException(DigitsSequence siDigitsToCheck,
  198.             int baseLength,int numberOfVerifierDigits) throws IllegalArgumentException {
  199.         throw new IllegalArgumentException(
  200.                 String.format(ERROR,
  201.                         siDigitsToCheck.toString(),
  202.                         siDigitsToCheck.length(),
  203.                         baseLength,
  204.                         numberOfVerifierDigits));
  205.     }
  206.    
  207.     /**
  208.      * cont�m apenas m�todos estaticos.
  209.      */
  210.     private VerifierDigits(){}
  211. }
Advertisement
Add Comment
Please, Sign In to add comment