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 org.junit.Assert;
25  
26  
27  /**
28   * EAN-13 Check Digit Test.
29   *
30   * @version $Revision$
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                  "AE070331234567890123456",       // United Arab Emirates
54                  "AL47212110090000000235698741",  // Albania
55                  "AT611904300234573201",          // Austria
56                  "AZ21NABZ00000000137010001944",  // Azerbaijan
57                  "BA391290079401028494",          // Bosnia and Herzegovina
58                  "BE62510007547061",              // Belgium
59                  "BE68539007547034",              // Belgium
60                  "BG80BNBG96611020345678",        // Bulgaria
61                  "BH67BMAG00001299123456",        // Bahrain
62                  "BR1800000000141455123924100C2", // Brazil
63                  "BY13NBRB3600900000002Z00AB00",  // Belarus
64                  "CH3900700115201849173",         // Switzerland
65                  "CH9300762011623852957",         // Switzerland
66                  "CR05015202001026284066",        // Costa Rica
67                  "CY17002001280000001200527600",  // Cyprus
68                  "CZ6508000000192000145399",      // Czechoslovakia
69                  "DE89370400440532013000",        // Germany
70                  "DK5000400440116243",            // Denmark
71                  "DO28BAGR00000001212453611324",  // Dominican Republic
72                  "EE382200221020145685",          // Estonia
73                  "ES8023100001180000012345",      // Spain
74                  "FI2112345600000785",            // Finland
75                  "FO6264600001631634",            // Denmark (Faroes)
76                  "FR1420041010050500013M02606",   // France
77                  "GB29NWBK60161331926819",        // UK
78                  "GI75NWBK000000007099453",       // Gibraltar
79                  "GL8964710001000206",            // Denmark (Greenland)
80                  "GR1601101250000000012300695",   // Greece
81                  "GT82TRAJ01020000001210029690",  // Guatemala
82                  "HR1210010051863000160",         // Croatia
83                  "HU42117730161111101800000000",  // Hungary
84                  "IE29AIBK93115212345678",        // Ireland
85                  "IL620108000000099999999",       // Israel
86                  "IQ98NBIQ850123456789012",       // Iraq
87                  "IS140159260076545510730339",    // Iceland
88                  "IT60X0542811101000000123456",   // Italy
89                  "JO94CBJO0010000000000131000302",// Jordan
90                  "KW81CBKU0000000000001234560101",// Kuwait
91                  "KZ86125KZT5004100100",          // Kazakhstan
92                  "LB62099900000001001901229114",  // Lebanon
93                  "LC55HEMM000100010012001200023015",//Saint Lucia
94                  "LI21088100002324013AA",         // Liechtenstein (Principality of)
95                  "LT121000011101001000",          // Lithuania
96                  "LU280019400644750000",          // Luxembourg
97                  "LV80BANK0000435195001",         // Latvia
98                  "MC5811222000010123456789030",   // Monaco
99                  "MD24AG000225100013104168",      // Moldova
100                 "ME25505000012345678951",        // Montenegro
101                 "MK07250120000058984",           // Macedonia, Former Yugoslav Republic of
102                 "MR1300020001010000123456753",   // Mauritania
103                 "MT84MALT011000012345MTLCAST001S",// Malta
104                 "MU17BOMM0101101030300200000MUR",// Mauritius
105                 "NL39RABO0300065264",            // Netherlands
106                 "NL91ABNA0417164300",            // Netherlands
107                 "NO9386011117947",               // Norway
108                 "PK36SCBL0000001123456702",      // Pakistan
109                 "PL27114020040000300201355387",  // Poland
110                 "PL60102010260000042270201111",  // Poland
111                 "PS92PALS000000000400123456702", // Palestine, State of
112                 "PT50000201231234567890154",     // Portugal
113                 "QA58DOHB00001234567890ABCDEFG", // Qatar
114                 "RO49AAAA1B31007593840000",      // Romania
115                 "RS35260005601001611379",        // Serbia
116                 "SA0380000000608010167519",      // Saudi Arabia
117                 "SC18SSCB11010000000000001497USD",// Seychelles
118                 "SE3550000000054910000003",      // Sweden
119                 "SI56191000000123438",           // Slovenia
120                 "SK3112000000198742637541",      // Slovak Republic
121                 "SM86U0322509800000000270100",   // San Marino
122                 "ST68000100010051845310112",     // Sao Tome and Principe
123                 "SV62CENR00000000000000700025",  // El Salvador
124                 "TL380080012345678910157",       // Timor-Leste
125                 "TN5910006035183598478831",      // Tunisia
126                 "TR330006100519786457841326",    // Turkey
127                 "UA213223130000026007233566001", // Ukraine
128                 "VA59001123000012345678",        // Vatican City State
129                 "VG96VPVG0000012345678901",      // Virgin Islands, British
130                 "XK051212012345678906",          // Republic of Kosovo
131 
132                 // Codes AA and ZZ will never be used as ISO countries nor in IBANs
133                 // add some dummy calculated codes to test the limits
134                 // Current minimum length is Norway = 15
135                 // Current maximum length is Malta  = 31
136                 // N.B. These codes will fail online checkers which validate the IBAN format
137                 //234567890123456789012345678901
138                 "AA0200000000053",
139                 "AA9700000000089",
140                 "AA9800000000071",
141                 "ZZ02ZZZZZZZZZZZZZZZZZZZZZZZZZ04",
142                 "ZZ97ZZZZZZZZZZZZZZZZZZZZZZZZZ40",
143                 "ZZ98ZZZZZZZZZZZZZZZZZZZZZZZZZ22",
144                 };
145         /*
146          *  sources
147          *  https://intranet.birmingham.ac.uk/finance/documents/public/IBAN.pdf
148          *  http://www.paymentscouncil.org.uk/resources_and_publications/ibans_in_europe/
149          */
150         invalid = new String[] {
151                 "510007+47061BE63",
152                 "IE01AIBK93118702569045",
153                 "AA0000000000089",
154                 "AA9900000000053",
155         };
156         zeroSum = null;
157         missingMessage = "Invalid Code length=0";
158 
159     }
160 
161     /**
162      * Test zero sum
163      */
164     @Override
165     public void testZeroSum() {
166         // ignore, don't run this test
167 
168         // example code used to create dummy IBANs
169 //        try {
170 //            for(int i=0; i<97;i++) {
171 //                String check = String.format("ZZ00ZZZZZZZZZZZZZZZZZZZZZZZZZ%02d", new Object[]{Integer.valueOf(i)});
172 //                String chk = routine.calculate(check);
173 //                if (chk.equals("97")||chk.equals("98")||chk.equals("02")) {
174 //                    System.out.println(check+ " "+chk);
175 //                }
176 //            }
177 //        } catch (CheckDigitException e) {
178 //            e.printStackTrace();
179 //        }
180     }
181 
182     /**
183      * Returns an array of codes with invalid check digits.
184      *
185      * @param codes Codes with valid check digits
186      * @return Codes with invalid check digits
187      */
188     @Override
189     protected String[] createInvalidCodes(String[] codes) {
190         List<String> list = new ArrayList<String>();
191 
192         // create invalid check digit values
193         for (int i = 0; i < codes.length; i++) {
194             String code = removeCheckDigit(codes[i]);
195             String check  = checkDigit(codes[i]);
196             for (int j = 2; j <= 98; j++) { // check digits can be from 02-98 (00 and 01 are not possible)
197                 String curr =  j > 9 ? "" + j : "0" + j;
198                 if (!curr.equals(check)) {
199                     list.add(code.substring(0, 2) + curr + code.substring(4));
200                 }
201             }
202         }
203 
204         return list.toArray(new String[list.size()]);
205     }
206 
207     /**
208      * Returns a code with the Check Digits (i.e. characters 3&4) set to "00".
209      *
210      * @param code The code
211      * @return The code with the zeroed check digits
212      */
213     @Override
214     protected String removeCheckDigit(String code) {
215         return code.substring(0, 2) + "00" + code.substring(4);
216     }
217 
218     /**
219      * Returns the check digit (i.e. last character) for a code.
220      *
221      * @param code The code
222      * @return The check digit
223      */
224     @Override
225     protected String checkDigit(String code) {
226         if (code == null || code.length() <= checkDigitLth) {
227             return "";
228         }
229        return code.substring(2, 4);
230     }
231 
232     public void testOther() throws Exception {
233         BufferedReader rdr = null;
234         try {
235             rdr = new BufferedReader(
236                     new InputStreamReader(
237                             this.getClass().getResourceAsStream("IBANtests.txt"),"ASCII"));
238             String line;
239             while((line=rdr.readLine()) != null) {
240                 if (!line.startsWith("#") && line.length() > 0) {
241                     if (line.startsWith("-")) {
242                         line = line.substring(1);
243                         Assert.assertFalse(line, routine.isValid(line.replaceAll(" ", "")));
244                     } else {
245                         Assert.assertTrue(line, routine.isValid(line.replaceAll(" ", "")));
246                     }
247                 }
248             }
249         } finally {
250             if (rdr != null) {
251                 rdr.close();
252             }
253         }
254     }
255 }