Engee documentation
Notebook

The CUSIP check digit verification algorithm

This example examines the implementation of the CUSIP check digit algorithm in the Julia programming language. We'll look at how the code works and what it's for.

Introduction

What is CUSIP?

CUSIP (Committee on Uniform Securities Identification Procedures) is a standard used in the United States and Canada to identify financial instruments such as stocks and bonds. Each CUSIP consists of 9 characters, where the last 9th character is a check digit, which is calculated using a specific algorithm.

Why do I need a check digit?

The check digit allows you to check whether the CUSIP has been entered or transmitted correctly. This helps to avoid errors when entering data and increases the reliability of systems working with financial instruments.

The structure of the CUSIP module

Consider the code:

In [ ]:
module CUSIP
    function _lastdigitcusip(input::AbstractString)
        input = uppercase(input)  # We reduce the string to upper case
        s = 0                     # A variable for accumulating the amount

        for (i, c) in enumerate(input)  # We go through each character of the string with the index
            if isdigit(c)
                v = Int(c) - 48           # Numbers: '0'-'9' -> 0-9
            elseif isletter(c)
                v = Int(c) - 64 + 9       # Letters: 'A'-'Z' -> 10-35, then +9
            elseif c == '*'
                v = 36                    # Special character
            elseif c == '@'
                v = 37                    # Special character
            elseif c == '#'
                v = 38                    # Special character
            end

            if iseven(i); v *= 2 end    # If the position is even, multiply by 2
            s += div(v, 10) + rem(v, 10) # Adding tens and ones
        end

        # Calculating the check digit
        return Char(rem(10 - rem(s, 10), 10) + 48)
    end

    checkdigit(input::AbstractString) = input[9] == _lastdigitcusip(input[1:8])
    
end # module CUSIP
Out[0]:
Main.CUSIP

Module CUSIP encapsulates functions related to checking CUSIP codes. This is convenient so as not to clog up the global namespace.

Function _lastdigitcusip calculates the check digit based on the first 8 characters of CUSIP.

Function checkdigit checks whether the 9th CUSIP character matches the calculated check digit.

How the algorithm works:
  1. Each character of the string is converted to a numeric value:
  • Digits from 0 to 9.
    • Letters from A to Z are converted to numbers from 10 to 35.
    • Special characters have fixed meanings.
  1. If the position of the symbol is even (counted), its value is multiplied by 2.
  2. The resulting value is divided into tens and ones, which are summed up.
  3. A check digit is calculated based on the total amount.

Checking codes

In [ ]:
for code in ("037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105")
    println("$code is ", CUSIP.checkdigit(code) ? "correct." : "not correct.")
end
037833100 is correct.
17275R102 is correct.
38259P508 is correct.
594918104 is correct.
68389X106 is not correct.
68389X105 is correct.

Several CUSIP codes are checked for correctness here. A function is called for each one checkdigit, and the result is displayed.

Conclusion

We have reviewed the implementation of the CUSIP check digit verification algorithm in the Julia language. The functions of calculating the check digit and verifying the correctness of the code were analyzed. This is useful for systems working with financial instruments where data accuracy is important. The implementation shows how to work efficiently with strings and numbers in Julia using built-in functions and logical constructs.

The example was developed using materials from Rosetta Code