Late Night Check Digit Routines - National Provider Identifier

Check digit routines are fun. There is one for the “National Provider Identifier” that a friend alerted me to this evening. He undertook implementing the algorithm in Perl, and I agreed to do a version of it in Ruby (my new favorite language). Below, I’ve include the source, replete with comments that I implemented the algorithm by. This code is provided with NO WARRANTY. Let me know if you use this code, or if you find problems with it.

Download Link: National Provider Identifier Ruby Code

If you’re looking for more information on this topic, a couple of links are:

http://www.claredi.com/download/npi_resources.php
http://www.medavanthealth.com/implementation/npi/NPI_check_digit.pdf


#!/usr/bin/env ruby
# NPI Validation Routine

# The NPI validation is done as follows:
# 1 ) For the purposes of this validation routine, isolate the last
#    digit of the NPI and do not use it in any steps outlined below;
# 2 ) Precede the NPI with 80840;
# 3 ) Double the value of alternate digits, beginning with the
#    rightmost digit, remember that the check digit is not to be used;
# 4 ) Total the value of the individual digits from step #3;
# 5 ) Total the value of the unaffected digits;
# 6 ) Add the two sums from steps #4 and #5;
# 7 ) Take the sum of step #6 and go to the next higher number
#    ending in zero;
# 8 ) Subtract the sum of step #6 from the next higher number
#    ending in zero from step #7;
# 9 ) If the value in step #8 matches the last digit in the
#    submitted NPI, the NPI is valid.
#

# Example of Check Digit Validation of the NPI

# The NPI submitted is 1234567893. The NPI validation is done as follows:
# 1 ) For the purposes of this validation routine, isolate the last
#    digit of the NPI (3) and do not use it in any steps outlined below;
# 2 ) Precede the NPI with 80840 (8 0 8 4 0 1 2 3 4 5 6 7 8 9 3);
# 3 ) Double the value of alternate digits, beginning with the
#    rightmost digit, remember that the check digit is not to be used (0 8 2
#    6 10 14 18);
# 4 ) Total the value of the individual digits from step #3
#    (0+8+2+6+1+0+1+4+1+8) which equals 31;
# 5 ) Total the value of the unaffected digits (8+6+4+2+0+8+8)
#    which equals 36;
# 6 ) Add the two sums from steps #4 and #5 (31+36) which equals 67;
# 7 ) Take the sum of step #6 and go to the next higher number
#    ending in zero which is 70;
# 8 ) Subtract the sum of step #6 from the next higher number
#    ending in zero from step #7 (70-67) and the value is 3;
# 9 ) The value in step #8 matches the last digit in the submitted
#    NPI, therefore the NPI is valid.

# try running with: ./npi.rb 1234567893 1234567891 9876543213

# prime the ARGV pump, if nothing was passed in
ARGV[0] ||= "1234567893"
ARGV.each { |npi_orig|
  #convert to array, leave off last digit, reverse it, convert to integer
  npi = ("80840" + npi_orig[0..-2]).scan(/./).reverse.collect {|digit| digit.to_i}
  total = 0;
  npi.each_index {|index|
    npi[index] = npi[index] * 2 unless ((index % 2) > 0);
    # tally up the digits into total, even if there are multiple
    npi[index].to_s.scan(/./).each{|digit| total += digit.to_i}
  }
  status = (npi_orig[-1..-1] == ((((total + 10) / 10).to_i * 10) - total).to_s)
                  ? "" :" *NOT* "
  puts "The number #{npi_orig} is#{status}a valid NPI"
}



Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word