View Javadoc
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.BufferedReader;
20  import java.io.InputStreamReader;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import junit.framework.Assert;
25  
26  
27  /**
28   * EAN-13 Check Digit Test.
29   *
30   * @version $Revision: 1713572 $
31   * @since Validator 1.4
32   */
33  public class IBANCheckDigitTest extends AbstractCheckDigitTest {
34  
35      /**
36       * Constructor
37       * @param name test name
38       */
39      public IBANCheckDigitTest(String name) {
40          super(name);
41          checkDigitLth = 2;
42      }
43  
44      /**
45       * Set up routine & valid codes.
46       */
47      protected void setUp() throws Exception {
48          super.setUp();
49          routine = IBANCheckDigit.IBAN_CHECK_DIGIT;
50          valid  = new String[]  {
51                  "AD1200012030200359100100",      // Andorra
52                  "AT611904300234573201",          // Austria
53                  "BE62510007547061",              // Belgium
54                  "BE68539007547034",              // Belgium
55                  "CH3900700115201849173",         // Switzerland
56                  "CH9300762011623852957",         // Switzerland
57                  "CY17002001280000001200527600",  // Cyprus
58                  "CZ6508000000192000145399",      // Czechoslovakia
59                  "DE89370400440532013000",        // Germany
60                  "DK5000400440116243",            // Denmark
61                  "EE382200221020145685",          // Estonia
62                  "ES8023100001180000012345",      // Spain
63                  "FI2112345600000785",            // Finland
64                  "FR1420041010050500013M02606",   // France
65                  "GB29NWBK60161331926819",        // UK
66                  "GI75NWBK000000007099453",       // Gibraltar
67                  "GR1601101250000000012300695",   // Greece
68                  "HU42117730161111101800000000",  // Hungary
69                  "IE29AIBK93115212345678",        // Ireland
70                  "IS140159260076545510730339",    // Iceland
71                  "IT60X0542811101000000123456",   // Italy
72                  "LT121000011101001000",          // Lithuania
73                  "LU280019400644750000",          // Luxembourg
74                  "LV80BANK0000435195001",         // Latvia
75                  "MT84MALT011000012345MTLCAST001S",// Malta
76                  "NL39RABO0300065264",            // Netherlands
77                  "NL91ABNA0417164300",            // Netherlands
78                  "NO9386011117947",               // Norway
79                  "PL27114020040000300201355387",  // Poland
80                  "PL60102010260000042270201111",  // Poland
81                  "PT50000201231234567890154",     // Portugal
82                  "SE3550000000054910000003",      // Sweden
83                  "SI56191000000123438",           // Slovenia
84                  "SK3112000000198742637541",      // Slovak Republic
85  
86                  // Codes AA and ZZ will never be used as ISO countries nor in IBANs
87                  // add some dummy calculated codes to test the limits
88                  // Current minimum length is Norway = 15
89                  // Current maximum length is Malta  = 31
90                  // N.B. These codes will fail online checkers which validate the IBAN format
91                  //234567890123456789012345678901
92                  "AA0200000000053",
93                  "AA9700000000089",
94                  "AA9800000000071",
95                  "ZZ02ZZZZZZZZZZZZZZZZZZZZZZZZZ04",
96                  "ZZ97ZZZZZZZZZZZZZZZZZZZZZZZZZ40",
97                  "ZZ98ZZZZZZZZZZZZZZZZZZZZZZZZZ22",
98                  };
99          /*
100          *  sources
101          *  https://intranet.birmingham.ac.uk/finance/documents/public/IBAN.pdf
102          *  http://www.paymentscouncil.org.uk/resources_and_publications/ibans_in_europe/
103          */
104         invalid = new String[] {
105                 "510007+47061BE63",
106                 "IE01AIBK93118702569045",
107                 "AA0000000000089",
108                 "AA9900000000053",
109         };
110         zeroSum = null;
111         missingMessage = "Invalid Code length=0";
112 
113     }
114 
115     /**
116      * Test zero sum
117      */
118     public void testZeroSum() {
119         // ignore, don't run this test
120 
121         // example code used to create dummy IBANs
122 //        try {
123 //            for(int i=0; i<97;i++) {
124 //                String check = String.format("ZZ00ZZZZZZZZZZZZZZZZZZZZZZZZZ%02d", new Object[]{Integer.valueOf(i)});
125 //                String chk = routine.calculate(check);
126 //                if (chk.equals("97")||chk.equals("98")||chk.equals("02")) {
127 //                    System.out.println(check+ " "+chk);
128 //                }
129 //            }
130 //        } catch (CheckDigitException e) {
131 //            e.printStackTrace();
132 //        }
133     }
134 
135     /**
136      * Returns an array of codes with invalid check digits.
137      *
138      * @param codes Codes with valid check digits
139      * @return Codes with invalid check digits
140      */
141     protected String[] createInvalidCodes(String[] codes) {
142         List<String> list = new ArrayList<String>();
143 
144         // create invalid check digit values
145         for (int i = 0; i < codes.length; i++) {
146             String code = removeCheckDigit(codes[i]);
147             String check  = checkDigit(codes[i]);
148             for (int j = 2; j <= 98; j++) { // check digits can be from 02-98 (00 and 01 are not possible)
149                 String curr =  j > 9 ? "" + j : "0" + j;
150                 if (!curr.equals(check)) {
151                     list.add(code.substring(0, 2) + curr + code.substring(4));
152                 }
153             }
154         }
155 
156         return (String[])list.toArray(new String[list.size()]);
157     }
158 
159     /**
160      * Returns a code with the Check Digits (i.e. characters 3&4) set to "00".
161      *
162      * @param code The code
163      * @return The code with the zeroed check digits
164      */
165     protected String removeCheckDigit(String code) {
166         return code.substring(0, 2) + "00" + code.substring(4);
167     }
168 
169     /**
170      * Returns the check digit (i.e. last character) for a code.
171      *
172      * @param code The code
173      * @return The check digit
174      */
175     protected String checkDigit(String code) {
176         if (code == null || code.length() <= checkDigitLth) {
177             return "";
178         }
179        return code.substring(2, 4);
180     }
181 
182     public void testOther() throws Exception {
183         BufferedReader rdr = null;
184         try {
185             rdr = new BufferedReader(
186                     new InputStreamReader(
187                             this.getClass().getResourceAsStream("IBANtests.txt"),"ASCII"));
188             String line;
189             while((line=rdr.readLine()) != null) {
190                 if (!line.startsWith("#") && line.length() > 0) {
191                     if (line.startsWith("-")) {
192                         line = line.substring(1);
193                         Assert.assertFalse(line, routine.isValid(line.replaceAll(" ", "")));
194                     } else {
195                         Assert.assertTrue(line, routine.isValid(line.replaceAll(" ", "")));
196                     }
197                 }
198             }
199         } finally {
200             if (rdr != null) {
201                 rdr.close();
202             }
203         }
204     }
205 }