A small Java library for dealing with International Bank Account Numbers (IBANs).

The IBAN class is intended for use in your domain types. IBAN objects enforce that their value is the correct length for its country code and that it passes checksum validation. The Modulo97 class exposes the checksum validation code for other purposes, such as live input validation.

The library is compatible for use in Android apps. It is in maintenance mode; I’ll occasionally update it to the latest version of the IBAN registry, but I don’t plan on developing any new features.


Grab a package from Github or get it from Maven Central:




    dependencies {
        compile 'nl.garvelink.oss:iban:1.6.1'


Obtain an IBAN instance using one of the static factory methods: valueOf( ) and parse( ). Methods throw java.lang.IllegalArgumentException on invalid input.

    // Obtain an instance of IBAN.
    IBAN iban = IBAN.valueOf( "NL91ABNA0417164300" );

    // toString() emits standard formatting, toPlainString() is compact.
    String s = iban.toString(); // "NL91 ABNA 0417 1643 00"
    String p = iban.toPlainString(); // "NL91ABNA0417164300"

    // Input may be formatted.
    iban = IBAN.valueOf( "BE68 5390 0754 7034" );

    // The valueOf() method returns null if its argument is null.
    IBAN.valueOf( null ); // null

    // The parse() method throws an exception if its argument is null.
    IBAN.parse( null ); // IllegalArgumentException

    // IBAN does not implement Comparable<T>, but a simple Comparator is provided.
    List<IBAN> ibans = getListOfIBANs();
    Collections.sort( ibans, IBAN.LEXICAL_ORDER );

    // The equals() and hashCode() methods are implemented.
    Map<IBAN, String> ibansAsKeys = Maps.newHashMap();
    ibansAsKeys.put( iban, "this is fine" );

    // You can use the Modulo97 class directly to compute or verify the check digits on an input.
    String candidate = "GB29 NWBK 6016 1331 9268 19";
    boolean valid = Modulo97.verifyCheckDigits( candidate ); // true

    // You can query whether an IBAN is of a SEPA-participating country
    boolean isSepa = IBAN.parse(candidate).isSEPA(); // true

    // You can query whether an IBAN is in the SWIFT Registry
    boolean isRegistered = IBAN.parse(candidate).isInSwiftRegistry(); // true

    // Modulo97 API methods take CharSequence, not just String.
    StringBuilder builder = new StringBuilder( "LU000019400644750000" );
    int checkDigits = Modulo97.calculateCheckDigits( builder ); // 28

    // Get the expected IBAN length for a country code:
    int length = CountryCodes.getLengthForCountryCode( "DK" );

    // Get the Bank Identifier and Branch Identifier (JDK 8):
    Optional<String> bankId = IBANFields.getBankIdentifier( iban );
    Optional<String> branchId = IBANFields.getBranchIdentifier( iban );

    // Get the Bank Identifier and Branch Identifier (pre-JDK 8):
    String bankId = IBANFieldsCompat.getBankIdentifier( iban );
    String branchId = IBANFieldsCompat.getBranchIdentifier( iban );

Version History

1.6.1: 20 September 2019

1.6.0: 23 August 2019

1.5.1: 12 September 2017

1.5: 26 February 2017

1.4: 4 May 2016

1.3: 5 July 2015

1.2: 1 September 2014

1.1: 25 October 2013

1.0: 30 May 2013

Design Choices

I like the Joda-Time library and I try to follow the same design principles. I’m explicitly targetting Android, which rules out some modern Java language constructs. I’m trying to keep the library as simple as I can.



If you’re looking for a more comprehensive IBAN library, you may prefer iban4j.

Copyright 2019 Barend Garvelink

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at


   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   See the License for the specific language governing permissions and
   limitations under the License.