Search code examples
javac#algorithmfinancecheck-digit

How to generate a CUSIP check digit


CUSIPs are a 9-digit alphanumeric code for uniquely identifying a financial security.

https://en.wikipedia.org/wiki/CUSIP

They were invented in the 1964, and given the reliability of data transmission in the 60's, the 9th digit is actually a check digit used to confirm the validity of the first 8 characters. Sometimes, even today, you might find reason to want to validate a CUSIP, or perhaps a company or service obnoxiously decides to only transmit the 8-character CUSIP, even though this defeats the purpose of a check digit.

The procedure to generate the check digit is:

  1. Convert non-numeric digits to values according to their ordinal position in the alphabet plus 9 (A=10, B=11,...Z=35) and converting the characters *=36, @=37, #=38.

  2. Multiply every even digit by 2

  3. If the result of the multiplication is a two-digit number, add the digits together. (12 = 1 + 2 = 3)

  4. Get the sum of all values.

  5. Get the floored value of this operation: (10 - (sum modulo 10)) modulo 10.

What is the best/simplest way to get this value in C#?


Solution

  • public string GenerateCheckDigit(string cusip)
    {        
        int sum = 0;
        char[] digits = cusip.ToUpper().ToCharArray();
        string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#";
    
        for (int i = 0; i < digits.Length; i++)
        {
            int val;
            if (!int.TryParse(digits[i].ToString(), out val))
                val = alphabet.IndexOf(digits[i]) + 10;
            
            if ((i % 2) != 0)
                val *= 2;
    
            val = (val % 10) + (val / 10);
            
            sum += val;
        }
        
        int check = (10 - (sum % 10)) % 10;
    
        return check.ToString();
    }
    

    Edit:

    .NET Fiddle demonstrating this: https://dotnetfiddle.net/kspQWl