/* * This file is part of Bitsquare. * * Bitsquare is free software: you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * Bitsquare is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public * License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Bitsquare. If not, see <http://www.gnu.org/licenses/>. */ package io.bitsquare.gui.util.validation; import java.math.BigInteger; import java.util.Locale; // TODO Does not yet recognize special letters like ä, ö, ü, å, ... as invalid characters public final class IBANValidator extends InputValidator { /////////////////////////////////////////////////////////////////////////////////////////// // Public methods /////////////////////////////////////////////////////////////////////////////////////////// @Override public ValidationResult validate(String input) { // TODO Add validation for primary and secondary IDs according to the selected type // IBAN max 34 chars, shortest is Norwegian with 15 chars, BBAN may include letters // bic: max 11 char // check input length first if (isStringInRange(input, 15, 34)) { input = input.toUpperCase(Locale.ROOT); // ensure upper case // check if country code is letters and checksum numeric if (!( Character.isLetter(input.charAt(0)) && Character.isLetter(input.charAt(1)) )) return new ValidationResult(false, "Country code invalid"); if (!( Character.isDigit(input.charAt(2)) && Character.isDigit(input.charAt(3)) )) return new ValidationResult(false, "Checksum must be numeric"); // reorder IBAN to format <account number> <country code> <checksum> String input2 = new String(input.substring(4, input.length()) + input.substring(0,4)); // check if input is alphanumeric and count included letters int charCount = 0; char ch; for (int k=0; k<input2.length(); k++) { ch = input2.charAt(k); if (Character.isLetter(ch)) charCount++; else if (!Character.isDigit(ch)) return (new ValidationResult(false, "Non-alphanumeric character detected")); } // create final char array for checksum validation char [] charArray = new char[input2.length()+charCount]; int i = 0; int tmp; for (int k=0; k<input2.length(); k++) { ch = input2.charAt(k); if (Character.isLetter(ch)) { tmp = ch - ('A' - 10); // letters are transformed to two digit numbers A->10, B->11, ... String s = Integer.toString(tmp); charArray[i++] = s.charAt(0); // insert transformed charArray[i++] = s.charAt(1); // letters into char array } else charArray[i++] = ch; // transfer digits directly to char array } // System.out.print(Arrays.toString(charArray) + '\t'); BigInteger bigInt = new BigInteger(new String(charArray)); int result = bigInt.mod(new BigInteger(Integer.toString(97))).intValue(); if (result == 1) return new ValidationResult(true); else return new ValidationResult(false, "IBAN checksum is invalid"); } // return new ValidationResult(false, BSResources.get("validation.accountNrChars", "15 - 34")); return new ValidationResult(false, "Number must have length 15 to 34 chars."); } /////////////////////////////////////////////////////////////////////////////////////////// // Private methods /////////////////////////////////////////////////////////////////////////////////////////// }