
Offers IBAN validation, formatting, and retrieval of country-specific details, with immutable objects, non-empty valid IBANs, and SEPA/SWIFT registry checks. Supports multi-platform environments.
This Kotlin Multiplatform library is a continuation and re-implementation of the original java-iban library by Barend Garvelink. It delivers IBAN validation, formatting, and country-specific IBAN details. The library is aimed to fulfill the same features as the original but in a Kotlin Multiplatform environment.
⚠ Important Note: The API of this library is still evolving and not yet stable. Expect breaking changes until the API stabilizes in a future release.
The original java-iban library laid a solid foundation for IBAN validation and utility functions in Java environments. This library reimagines those capabilities with Kotlin's cross-platform features, making it ready for use on multiple platforms such as JVM, Android, iOS, and more.
Obtain an Iban instance using one of the static factory methods: valueOf( ) and parse( ). Methods throw IllegalArgumentException on invalid input.
// Obtain an instance of Iban.
val iban = Iban.valueOf( "NL91ABNA0417164300" )
// toString() emits standard formatting, toPlainString() is compact.
val formatted = iban.toString() // "NL91 ABNA 0417 1643 00"
val plain = iban.toPlainString() // "NL91ABNA0417164300"
// Input may be formatted.
val anotherIban = Iban.valueOf( "BE68 5390 0754 7034" )
// IBAN implements Comparable<T>.
val ibans = getListOfIBANs()
ibans.sorted() // sorts in lexical order
// The equals() and hashCode() methods are implemented.
val ibansAsKeys = mutableMapOf<Iban, String>()
ibansAsKeys.put( iban, "this is fine" )
// You can use the Modulo97 class directly to compute or verify the check digits on an input.
val candidate = "GB29 NWBK 6016 1331 9268 19"
val valid = Modulo97.verifyCheckDigits( candidate ) // true
// Compose the IBAN for a country and BBAN
Iban.compose( "BI", "201011067444" ) // BI43201011067444
// You can query whether an IBAN is of a SEPA-participating country
val isSepa = Iban.parse(candidate).isSEPA // true
// You can query whether an IBAN is in the SWIFT Registry
val isRegistered = Iban.parse(candidate).isInSwiftRegistry // true
// Modulo97 API methods take CharSequence, not just String.
val builder = StringBuilder( "LU000019400644750000" )
val checkDigits = Modulo97.calculateCheckDigits( builder ) // 28
// Modulo97 API can calculate check digits, also for non-iban inputs.
// It does assume/require that the check digits are on indices 2 and 3.
Modulo97.calculateCheckDigits( "GB", "NWBK60161331926819" ) // 29
Modulo97.calculateCheckDigits( "XX", "X" ) // 50
// Get the expected IBAN length for a country code:
val expectedLength = CountryCodes.getLengthForCountryCode( "DK" )
// Get the Bank Identifier and Branch Identifier:
val bankId: String? = CountryCodes.getBankIdentifier( iban )
val branchId: String? = CountryCodes.getBranchIdentifier( iban )
// Get the Bank Identifier and Branch Identifier as Java Optional:
val bankId = IbanFields.getBankIdentifier( iban ) // Optional<String>
val branchId = IbanFields.getBranchIdentifier( iban ) // Optional<String>I (Barend) like the Joda-Time library, and I try to follow the same design principles. I'm explicitly targetting Android, which at the time this library started was still on Java 1.6. I'm trying to keep the library as simple as I can.
Iban objects are immutable, and the Iban therein is non-empty and valid. There is no support for partial or invalid IBANs. Note that "valid" isn't as strict as it could be:
QA2!n4!a21!c) is not enforced. This seems to me like more work than necessary. The modulo-97 checksum catches most input errors anyway, and I don't want to force a memory-hungry regex check onto Android users. Speaking of Android, this mask could be used for keyboard switching on an Iban EditText, but that's for a different open-source project.Iban.valueOf() method. This, to me, would look too much like Joda-Time's pluggable Chronology system, which leads to PoLS violations (background: Why JSR-310 isn't Joda-Time).Iban class. Currently, that's the support for extracting Bank and Branch identifiers, which lives in the CountryCode class.Adopted design choices from Java library and going to do next:
As this is still an evolving library with an unstable API, contributions are welcome! Join the development journey and help shape a modern, multiplatform IBAN utility library.
This project follows the same licensing model as the original library and is licensed under the Apache License 2.0.
This Kotlin Multiplatform library is a continuation and re-implementation of the original java-iban library by Barend Garvelink. It delivers IBAN validation, formatting, and country-specific IBAN details. The library is aimed to fulfill the same features as the original but in a Kotlin Multiplatform environment.
⚠ Important Note: The API of this library is still evolving and not yet stable. Expect breaking changes until the API stabilizes in a future release.
The original java-iban library laid a solid foundation for IBAN validation and utility functions in Java environments. This library reimagines those capabilities with Kotlin's cross-platform features, making it ready for use on multiple platforms such as JVM, Android, iOS, and more.
Obtain an Iban instance using one of the static factory methods: valueOf( ) and parse( ). Methods throw IllegalArgumentException on invalid input.
// Obtain an instance of Iban.
val iban = Iban.valueOf( "NL91ABNA0417164300" )
// toString() emits standard formatting, toPlainString() is compact.
val formatted = iban.toString() // "NL91 ABNA 0417 1643 00"
val plain = iban.toPlainString() // "NL91ABNA0417164300"
// Input may be formatted.
val anotherIban = Iban.valueOf( "BE68 5390 0754 7034" )
// IBAN implements Comparable<T>.
val ibans = getListOfIBANs()
ibans.sorted() // sorts in lexical order
// The equals() and hashCode() methods are implemented.
val ibansAsKeys = mutableMapOf<Iban, String>()
ibansAsKeys.put( iban, "this is fine" )
// You can use the Modulo97 class directly to compute or verify the check digits on an input.
val candidate = "GB29 NWBK 6016 1331 9268 19"
val valid = Modulo97.verifyCheckDigits( candidate ) // true
// Compose the IBAN for a country and BBAN
Iban.compose( "BI", "201011067444" ) // BI43201011067444
// You can query whether an IBAN is of a SEPA-participating country
val isSepa = Iban.parse(candidate).isSEPA // true
// You can query whether an IBAN is in the SWIFT Registry
val isRegistered = Iban.parse(candidate).isInSwiftRegistry // true
// Modulo97 API methods take CharSequence, not just String.
val builder = StringBuilder( "LU000019400644750000" )
val checkDigits = Modulo97.calculateCheckDigits( builder ) // 28
// Modulo97 API can calculate check digits, also for non-iban inputs.
// It does assume/require that the check digits are on indices 2 and 3.
Modulo97.calculateCheckDigits( "GB", "NWBK60161331926819" ) // 29
Modulo97.calculateCheckDigits( "XX", "X" ) // 50
// Get the expected IBAN length for a country code:
val expectedLength = CountryCodes.getLengthForCountryCode( "DK" )
// Get the Bank Identifier and Branch Identifier:
val bankId: String? = CountryCodes.getBankIdentifier( iban )
val branchId: String? = CountryCodes.getBranchIdentifier( iban )
// Get the Bank Identifier and Branch Identifier as Java Optional:
val bankId = IbanFields.getBankIdentifier( iban ) // Optional<String>
val branchId = IbanFields.getBranchIdentifier( iban ) // Optional<String>I (Barend) like the Joda-Time library, and I try to follow the same design principles. I'm explicitly targetting Android, which at the time this library started was still on Java 1.6. I'm trying to keep the library as simple as I can.
Iban objects are immutable, and the Iban therein is non-empty and valid. There is no support for partial or invalid IBANs. Note that "valid" isn't as strict as it could be:
QA2!n4!a21!c) is not enforced. This seems to me like more work than necessary. The modulo-97 checksum catches most input errors anyway, and I don't want to force a memory-hungry regex check onto Android users. Speaking of Android, this mask could be used for keyboard switching on an Iban EditText, but that's for a different open-source project.Iban.valueOf() method. This, to me, would look too much like Joda-Time's pluggable Chronology system, which leads to PoLS violations (background: Why JSR-310 isn't Joda-Time).Iban class. Currently, that's the support for extracting Bank and Branch identifiers, which lives in the CountryCode class.Adopted design choices from Java library and going to do next:
As this is still an evolving library with an unstable API, contributions are welcome! Join the development journey and help shape a modern, multiplatform IBAN utility library.
This project follows the same licensing model as the original library and is licensed under the Apache License 2.0.