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