Skip to content

Instantly share code, notes, and snippets.

@lmonkiewicz
Created April 16, 2023 18:05
Show Gist options
  • Save lmonkiewicz/d000b111a135d3403dfd5bf2e1d21625 to your computer and use it in GitHub Desktop.
Save lmonkiewicz/d000b111a135d3403dfd5bf2e1d21625 to your computer and use it in GitHub Desktop.
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