Created
April 16, 2023 18:05
-
-
Save lmonkiewicz/d000b111a135d3403dfd5bf2e1d21625 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pl.effectivedev.iban.ibantest; | |
import java.math.BigInteger; | |
import java.time.LocalDate; | |
import java.util.Map; | |
import java.util.TreeMap; | |
public class IbanService { | |
Map<String, IbanStructure> structures = new TreeMap<>(); | |
{ | |
structures.put("PL", new IbanStructure( | |
28, | |
0, 2, // country code | |
LocalDate.now() | |
)); | |
} | |
Iban parse(String iban) { | |
var countryCode = iban.substring(0, 2); | |
var structure = structures.get(countryCode); | |
if (structure == null) { | |
return Iban.unsupportedCountry(iban, countryCode); | |
} | |
return new Iban(iban, countryCode, structure); | |
} | |
record IbanStructure( | |
int length, | |
int nationalIdPos, int nationalIdLen, | |
LocalDate mandatorySince | |
){} | |
public static class Iban { | |
private final String iban; | |
private final String countryCode; | |
private final IbanStructure structure; | |
Iban(String iban, String countryCode, IbanStructure structure) { | |
this.iban = iban; | |
this.countryCode = countryCode; | |
this.structure = structure; | |
} | |
public static Iban unsupportedCountry(String iban, String countryCode) { | |
return new Iban(iban, countryCode, null); | |
} | |
public boolean isValid() { | |
return isSupported() && hasValidLength() && hasValidChecksum(); | |
} | |
public boolean hasValidLength() { | |
if (isSupported()) { | |
return iban.length() == structure.length(); | |
} | |
return false; | |
} | |
public boolean hasValidChecksum() { | |
var rearranged = iban.substring(4) + iban.substring(0, 4); | |
var allDigits = rearranged | |
.replaceAll("A", "10") | |
.replaceAll("B", "11") | |
.replaceAll("C", "12") | |
.replaceAll("D", "13") | |
.replaceAll("E", "14") | |
.replaceAll("F", "15") | |
.replaceAll("G", "16") | |
.replaceAll("H", "17") | |
.replaceAll("I", "18") | |
.replaceAll("J", "19") | |
.replaceAll("K", "20") | |
.replaceAll("L", "21") | |
.replaceAll("M", "22") | |
.replaceAll("N", "23") | |
.replaceAll("O", "24") | |
.replaceAll("P", "25") | |
.replaceAll("Q", "26") | |
.replaceAll("R", "27") | |
.replaceAll("S", "28") | |
.replaceAll("T", "29") | |
.replaceAll("U", "30") | |
.replaceAll("V", "31") | |
.replaceAll("W", "32") | |
.replaceAll("X", "33") | |
.replaceAll("Y", "34") | |
.replaceAll("Z", "35"); | |
var reminder = new BigInteger(allDigits).mod(BigInteger.valueOf(97)); | |
return reminder.intValue() == 1; | |
} | |
public boolean isSupported() { | |
return structure != null; | |
} | |
public LocalDate getMandatoryCommenceDate() { return structure.mandatorySince(); } | |
public String getCountryCode() { return countryCode; }; | |
public String getIbanNationalId() { | |
if (isSupported()) { | |
final int beginPos = structure.nationalIdPos(); | |
return iban.substring(beginPos, beginPos + structure.nationalIdLen()); | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment