Search code examples
javachecksummodulo

How to verify LEI checksum in java?


I am following https://en.wikipedia.org/wiki/International_Bank_Account_Number to verify the checksum of Legal Entity Identifier(LEI) with the following code:

import java. math. BigInteger;

public class LEIChecksumVerifier{

    public final String [] leiChars = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
    public final String [] leiDigits = {"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35"};

    public boolean verifyLeiCheckSum(String lei){
        boolean result = false;
        String shiftedLei = "";
        String digitisedLei= "";
        BigInteger leiBigInt = new BigInteger("0");
        BigInteger leiDivisorBigInt = new BigInteger("97");
        BigInteger remainderBigInt = new BigInteger("0");

        if(lei != null){
            lei = lei.toUpperCase().trim();
            if(lei.length() == 20){
                //Step1: Shift the first 4 digits to the end
                shiftedLei =  lei.substring(4, 20).concat(lei.substring(0, 4));
                //System.out.println("LEI: "+lei+"\tShifted LEI: "+shiftedLei);
                digitisedLei= shiftedLei;
                //Step2: Replace the alphabets with their integer values
                for ( int e = 0; e < leiChars.length; e++){
                    digitisedLei= digitisedLei.replaceAll(leiChars[e], leiDigits[e]);
                }
                //System.out.println("LEI: "+lei+"\tShifted LEI: "+shiftedLei+"\tDigitised LEI: "+digitisedLei);
                leiBigInt = new BigInteger(digitisedLei);
                //System.out.println("LEI: "+lei+"\tShifted LEI: "+shiftedLei+"\tDigitised LEI: "+digitisedLei+"\t LEI Big Integer: "+leiBigInt);
                remainderBigInt = leiBigInt.mod(leiDivisorBigInt);
                System.out.println("LEI: "+lei+"\tShifted LEI: "+shiftedLei+"\tDigitised LEI: "+digitisedLei+"\t LEI Big Integer: "+leiBigInt+"\t "+lei+" mod 97 : "+remainderBigInt);
                //Step3: if digitiesedLEI mod 97 == 1, checksum is valid!
                result = remainderBigInt.equals(new BigInteger("1"));
            }else{
                System.out.println("Error: "+lei+" length "+lei.length()+" differs from its standard value 20!");
            }
        }else{
            System.out.println("Error: lei is null!");
        }
    System.out.println("LEI :"+lei+" has valid checksum:" + result+"!");
    return result;      
    }

    public static void main(String [] args){
        LEIChecksumVerifier lEIChecksumVerifier = new LEIChecksumVerifier();
        //LEI of British Broadcasting Corporation : 5493-00-0IBP32UQZ0KL-24     
        lEIChecksumVerifier.verifyLeiCheckSum("5493000IBP32UQZ0KL24");
    }
}

But, it gives invalid checksum for a valid LEI. Please guide me in proper LEI checksum verification!


Solution

  • It's hard to find details, but https://github.com/EDumdum/iso-17442-java has an implementation.

    The checksum in LEI is already at the end, all you have change in your code is skip the shifting step. Now it reports a valid checksum for me.