Check Digit Routine using Mod 10
Tuesday, October 28, 2008 at 01:33PM The following is a handy function that I wrote in SQL Server
to return a check
digit for a string of numbers (in my case, a scanline). It
uses the Luhn
Algorithm – also referred to as modulus 10. Starting
with a string of
numbers, the algorithm works as follows:
178009067 (this is our number string)
Now, starting with the first digit on the RIGHT, take the sum
of all digits,
doubling every other digit and adding them together. The
first digit we should
double is the second from the right. We would get:
7 + (1 + 2) + 0 + (1 + 8) + 0 + 0 + 8 + (1 + 4) + 1 = 33
Our check digit will be whatever we need to add to this total
to make it
divisible by 10. In this case our check digit is 7.
Here is a function that will automatically calculate a check
digit when it is
passed a string of numbers.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[fnCalcCheckDigit]
(@sOrig VARCHAR(34))
--
@sOrig represents the string you are sending to the function.
--
If you are calculating a check digit for an OCR scanline for
--
example, @sOrig should contain the full scanline. Make sure
--
your varchar is big enough to hold the string, but not
--
inefficiently large
RETURNS VARCHAR(1)
AS
BEGIN
DECLARE @i INT, @j INT, @total INT, @finish INT, @result BIT, @testMsg VARCHAR(50), @double BIT
--
@j will temporarily store the value of the string digit to be
--
added into the running total after each iteration
--
@finish will store the scanline and the check digit
--
@total will hold the running total and will be
--
incremented by @j
--
@double is a boolean variable that will represent if a
--
digit is odd or even (since every other digit must be
--
doubled and added to the running total.
SET @finish = 0
SET @total = 0
SET @sOrig = LTRIM(@sOrig)
SET @sOrig = RTRIM(@sOrig)
SET @i = LEN(@sOrig)
--
Always start with an odd digit - our first digit to be
--
doubled will be the second from the right
SET @double = 0
WHILE @i > 0
BEGIN
SELECT @j=(ASCII(SUBSTRING(@sOrig, @i, 1))-48)
IF @double = 1
BEGIN
SET @j = @j * 2
--
If the digit * 2 is a two digit number
--
(for example 8 * 2 = 16), then we need to add 1 + 6.
--
We can use 16 - 9, because any digit doubled minus
--
9 will equal the sum of the two digits that make
--
up the number.
IF @j > 9
BEGIN
SET @j = @j - 9
END
SET @double = 0
END
ELSE
BEGIN
--
Set this flag so we know to double the next digit
SET @double = 1
END
SET @total = @total + @j
SET @i = @i - 1
END
--
Take the modulus 10 - if it is equal to zero,
--
then check digit is zero, otherwise,
--
store the check digit in @finish
IF @total % 10 = 0
SELECT @finish = 0
ELSE
SELECT @finish = 10 - (@total % 10)
RETURN (@finish)
END
