MOD 11 Check Digit code in C# and sql

23. January 2010

 

Recently, I needed to generate a MOD 11 or Modulus 11 check digit calculation in c#.

So, I took a look at the MOD11 on wikipedia for the specification. 

  • Norwegian link here
  • English Translated by google here
  • Norwegian: Page 14 of bbs spec here

 

I searched around to see if someone had coded it and found a few examples for c#, but they all didn't seem to calculate it per the specification.  I broadened my search and found an excellant MOD11 check generator here.  The php code here was also straightforward, so I converted it to c#.  Perhaps, it could be optimized a little, but it is a small utility method, so I didn't bother.

Here is the code:

public static string CalculateMOD11(string controlNumber)
        {
            int i;
            int sum = 0;
            string checkDigit= string.Empty;
            
            //Set the weight beginning=2.
            int weightcount = 2;
            char[] tempArray = controlNumber.ToCharArray();
            //Reverse the control number
            Array.Reverse(tempArray);
            string controlNumberReversed = new string(tempArray);
            for (i = 0; i < controlNumberReversed.Length; i++)
            {
                //sets the weight count to loop from 2 up to 7.
                if (weightcount >7)
                {
                  //resets to 2 again.
                  weightcount=2;
                }
                sum += Convert.ToInt32(controlNumberReversed.Substring(i, 1),CultureInfo.InvariantCulture) * weightcount;
                weightcount++;
            }
            int remainder = sum % 11;
            switch (remainder)
            {
                case 0:
                    checkDigit = Convert.ToString(0, CultureInfo.InvariantCulture);
                    break;
                case 1:
                    checkDigit = "-";
                    break;
                default:
                    checkDigit = Convert.ToString((11 - remainder), CultureInfo.InvariantCulture);
                    break;
            }
            controlNumber = controlNumber + checkDigit;
            return controlNumber;
        }

I found out later that I needed a sql function for this also.  I took me a little time to convert this to a stored procedure as I not that good a writing code in sql.  

Below is the code, I am hopeful this will save time for you. :)

ALTER FUNCTION [dbo].[CreateMOD11]
(
	@ControlNumber Varchar(15)
)
RETURNS Varchar(16)
AS
BEGIN
	-- Declare the return variable here
		DECLARE @ReversedControlNumber Varchar(16)
        DECLARE @CharCount int
        DECLARE @Sum int
        DECLARE @TotalSum int
        DECLARE @WeightCount int
        DECLARE @Checkbit char(1)
		DECLARE @Remainder int

	-- reverse the control number
    select @ReversedControlNumber= reverse(@ControlNumber)

	select @CharCount=1
	select @TotalSum=0
	select @WeightCount=2
	WHILE @CharCount < Len(@ReversedControlNumber)+1
	BEGIN
	   --loop to 7 then repeat as per MOD11 spec. http://no.wikipedia.org/wiki/MOD11
	   IF @WeightCount > 7
	   BEGIN
		 select @WeightCount=2
	   END
	   select @Sum =Cast(Substring(@ReversedControlNumber,@CharCount,1)as int)* @WeightCount
	   select @TotalSum = @TotalSum + @Sum
	   select @CharCount= @CharCount +1
	   select @WeightCount= @WeightCount +1
	END
	select @Remainder=(@TotalSum % 11)
	Select @Checkbit= CASE @Remainder
						WHEN 0 THEN 0
						WHEN 1 THEN '-'
						ELSE CAST((11-@Remainder) as char(1))
					  END
    return @ControlNumber+@Checkbit
END

I found out that I needed mod 10, so here it is also. :)

(ALTER FUNCTION [dbo].[CreateMOD10]
(
	@ControlNumber Varchar(15)
)
RETURNS Varchar(16)
AS
BEGIN
	-- Declare the return variable here
	--Check digit count
	-- Declare the return variable here
	DECLARE @LengthInvoiceOID INT
	DECLARE @NumberOfExtraZeros INT
        DECLARE @NumZerosToInvoiceOID INT
	DECLARE @NewInvoiceOID Varchar(6)
	DECLARE @ControlNumber Varchar(16)
        DECLARE @CharCount int
        DECLARE @SplitSum int
	DECLARE @StringSum char(2)
        DECLARE @Sum int
        DECLARE @TotalSum int
        DECLARE @WeightCount int
        DECLARE @Checkbit char(1)
	DECLARE @Remainder int
	--initialize the variables
	select @CharCount=1
	select @TotalSum=0
	select @WeightCount=1
	WHILE @CharCount < Len(@ControlNumber)+1
	BEGIN
	   --loop to 2 then repeat as per MOD10 spec. http://no.wikipedia.org/wiki/MOD10
	   IF @WeightCount > 2
	   BEGIN
		 select @WeightCount=1
	   END
	   select @Sum =Cast(Substring(@ControlNumber,@CharCount,1)as int)* @WeightCount
       IF Len(@Sum) =2
        BEGIN
           select @StringSum=CAST(@SUM as char(2))
           select @SplitSum=CAST(SUBSTRING(@StringSum,1,1)as int)+CAST(SUBSTRING(@StringSum,2,1)as int)
		   select @TotalSum = @TotalSum + @SplitSum
        END
       ELSE
        BEGIN
			select @TotalSum = @TotalSum + @Sum
        END
	   select @CharCount= @CharCount +1
	   select @WeightCount= @WeightCount +1
	END
	select @Remainder=(@TotalSum % 10)
	Select @Checkbit= CASE @Remainder
						WHEN 0 THEN 0
						ELSE CAST((10-@Remainder) as char(1))
					  END
    return @ControlNumber+@Checkbit
END