Coverage Report - org.apache.commons.validator.routines.checkdigit.IBANCheckDigit
 
Classes in this File Line Coverage Branch Coverage Complexity
IBANCheckDigit
100%
25/25
91%
22/24
5
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.validator.routines.checkdigit;
 18  
 
 19  
 import java.io.Serializable;
 20  
 
 21  
 /**
 22  
  * <b>IBAN</b> (International Bank Account Number) Check Digit calculation/validation.
 23  
  * <p>
 24  
  * This routine is based on the ISO 7064 Mod 97,10 check digit calculation routine.
 25  
  * <p>
 26  
  * The two check digit characters in a IBAN number are the third and fourth characters
 27  
  * in the code. For <i>check digit</i> calculation/validation the first four characters are moved
 28  
  * to the end of the code.
 29  
  *  So <code>CCDDnnnnnnn</code> becomes <code>nnnnnnnCCDD</code> (where
 30  
  *  <code>CC</code> is the country code and <code>DD</code> is the check digit). For
 31  
  *  check digit calcualtion the check digit value should be set to zero (i.e.
 32  
  *  <code>CC00nnnnnnn</code> in this example.
 33  
  * <p>
 34  
  * Note: the class does not check the format of the IBAN number, only the check digits.
 35  
  * <p>
 36  
  * For further information see
 37  
  *  <a href="http://en.wikipedia.org/wiki/International_Bank_Account_Number">Wikipedia -
 38  
  *  IBAN number</a>.
 39  
  *
 40  
  * @version $Revision: 1441399 $ $Date: 2013-02-01 06:48:59 -0500 (Fri, 01 Feb 2013) $
 41  
  * @since Validator 1.4
 42  
  */
 43  
 public final class IBANCheckDigit implements CheckDigit, Serializable {
 44  
 
 45  
     private static final long serialVersionUID = -3600191725934382801L;
 46  
 
 47  
     /** Singleton IBAN Number Check Digit instance */
 48  1
     public static final CheckDigit IBAN_CHECK_DIGIT = new IBANCheckDigit();
 49  
 
 50  
     private static final long MAX = 999999999;
 51  
 
 52  
     private static final long MODULUS = 97;
 53  
 
 54  
     /**
 55  
      * Construct Check Digit routine for IBAN Numbers.
 56  
      */
 57  1
     public IBANCheckDigit() {
 58  1
     }
 59  
 
 60  
     /**
 61  
      * Validate the check digit of an IBAN code.
 62  
      *
 63  
      * @param code The code to validate
 64  
      * @return <code>true</code> if the check digit is valid, otherwise
 65  
      * <code>false</code>
 66  
      */
 67  
     public boolean isValid(String code) {
 68  2979
         if (code == null || code.length() < 5) {
 69  2
             return false;
 70  
         }
 71  
         try {
 72  2977
             int modulusResult = calculateModulus(code);
 73  2976
             return (modulusResult == 1);
 74  1
         } catch (CheckDigitException  ex) {
 75  1
             return false;
 76  
         }
 77  
     }
 78  
 
 79  
     /**
 80  
      * Calculate the <i>Check Digit</i> for an IBAN code.
 81  
      * <p>
 82  
      * <b>Note:</b> The check digit is the third and fourth
 83  
      * characters and and should contain value "<code>00</code>".
 84  
      *
 85  
      * @param code The code to calculate the Check Digit for
 86  
      * @return The calculated Check Digit as 2 numeric decimal characters, e.g. "42"
 87  
      * @throws CheckDigitException if an error occurs calculating
 88  
      * the check digit for the specified code
 89  
      */
 90  
     public String calculate(String code) throws CheckDigitException {
 91  34
         if (code == null || code.length() < 5) {
 92  2
             throw new CheckDigitException("Invalid Code length=" +
 93  
                     (code == null ? 0 : code.length()));
 94  
         }
 95  32
         int modulusResult = calculateModulus(code);
 96  31
         int charValue = (98 - modulusResult);
 97  31
         String checkDigit = Integer.toString(charValue);
 98  31
         return (charValue > 9 ? checkDigit : "0" + checkDigit);
 99  
     }
 100  
 
 101  
     /**
 102  
      * Calculate the modulus for a code.
 103  
      *
 104  
      * @param code The code to calculate the modulus for.
 105  
      * @return The modulus value
 106  
      * @throws CheckDigitException if an error occurs calculating the modulus
 107  
      * for the specified code
 108  
      */
 109  
     private int calculateModulus(String code) throws CheckDigitException {
 110  3009
         String reformattedCode = code.substring(4) + code.substring(0, 4);
 111  3009
         long total = 0;
 112  69652
         for (int i = 0; i < reformattedCode.length(); i++) {
 113  66645
             int charValue = Character.getNumericValue(reformattedCode.charAt(i));
 114  66645
             if (charValue < 0 || charValue > 35) {
 115  2
                 throw new CheckDigitException("Invalid Character[" +
 116  
                         i + "] = '" + charValue + "'");
 117  
             }
 118  66643
             total = (charValue > 9 ? total * 100 : total * 10) + charValue;
 119  66643
             if (total > MAX) {
 120  7178
                 total = (total % MODULUS);
 121  
             }
 122  
         }
 123  3007
         return (int)(total % MODULUS);
 124  
     }
 125  
 
 126  
 }