Luhn Algorithm (Modulus 10) in Dynamics NAV C/AL & Business Central code - Creating a check Digit
Ephraim_07
Member Posts: 9
Hello people,
So a client required Luhn algorithm (also known as modulus 10 or mod 10) to be used on their database to create a check digit for a given number and a valid OCR reference for payments. I saw some solutions on this website that did not work so I decided to post a good solution below:
For Luhn algorithm, you need a Payload (the original number) to generate a check digit. The check digit will be added to the code to make a valid number.
To read More on the Luhn Algorithm, see here >> https://simplycalc.com/luhn-calculate.php
1. Create a Codeunit with the following data types in your C/AL Locals:
Name DataType Subtype Length
i Integer
LengthOfDigit Integer
Digits Code 250
Product BigInteger
SumProduct BigInteger
CurrentNumber BigInteger
CurrentStringPosition BigInteger
ReversePosition BigInteger
And the following Parameters:
Var Name DataType Subtype Length
No OrigNumber BigInteger
2. View the code below:
3. After you have generated the code I recommend you convert it to text/Code so that you can combine it into a new number that is OCR compliant, e.g.
So a client required Luhn algorithm (also known as modulus 10 or mod 10) to be used on their database to create a check digit for a given number and a valid OCR reference for payments. I saw some solutions on this website that did not work so I decided to post a good solution below:
For Luhn algorithm, you need a Payload (the original number) to generate a check digit. The check digit will be added to the code to make a valid number.
To read More on the Luhn Algorithm, see here >> https://simplycalc.com/luhn-calculate.php
1. Create a Codeunit with the following data types in your C/AL Locals:
Name DataType Subtype Length
i Integer
LengthOfDigit Integer
Digits Code 250
Product BigInteger
SumProduct BigInteger
CurrentNumber BigInteger
CurrentStringPosition BigInteger
ReversePosition BigInteger
And the following Parameters:
Var Name DataType Subtype Length
No OrigNumber BigInteger
2. View the code below:
LOCAL GenerateCheckDigit(OrigNumber : Code[249]) CheckDigitNumber : Code[1]
IF COPYSTR(OrigNumber,1,1) = '-' THEN
ERROR('The number to evaluate must be a positive number. Number provided is %1',OrigNumber);
LengthOfDigit := STRLEN(OrigNumber); //Get the length of the string because this will allow to define how long the loop below will be.
FOR i := LengthOfDigit DOWNTO 1 DO BEGIN
CLEAR(ReversePosition); CLEAR(Product);
ReversePosition := (LengthOfDigit + 1) - i; //this will get the REVERSE position of the digit because Luhn Algorithm starts from right to left.
// This means the last digit in the number is processed first.
Digits[i] := COPYSTR(OrigNumber,ReversePosition,1); // Get the individual digit in that position with an array. The digit must be converted to a Code variable because only Text and Code variable can be seperated into their individual parts in NAV.
// e.g. 231123 = [2,3,1,1,2,3]
CheckLettersInNumber(Digits[i]);
//Check if the *Position* of the digit is an odd number. All odd numbers will always be [ i MOD 2 = 1 ]
// If Odd position, then multiply by 2, else multiply by 1. This is how the Algorithm works
//--------------------------------------------------------------
IF i MOD 2 <> 0 THEN BEGIN
EVALUATE(Product,Digits[i]); //Convert the code back to integer/number for multiplication
Product := Product * 2;
END ELSE BEGIN
EVALUATE(Product,Digits[i]);
Product := Product * 1;
END;
//-----If the product computed above is greater than 9, get the sum of the individual digits (digit sum) e.g. 12 will be 1 + 2 = 3
CASE Product OF
10:
Product := 1 + 0;
11:
Product := 1 + 1;
12:
Product := 1 + 2;
13:
Product := 1 + 3;
14:
Product := 1 + 4;
15:
Product := 1 + 5;
16:
Product := 1 + 6;
17:
Product := 1 + 7;
18:
Product := 1 + 8;
19:
Product := 1 + 9;
END;
SumProduct := SumProduct + Product;
//Get the Modulus of the sum of figures
IF SumProduct MOD 10 <> 0 THEN
CheckDigitNumber := FORMAT(10 - (SumProduct MOD 10))
ELSE
CheckDigitNumber := FORMAT(0); //If SumProduct MOD 10 is =10 then answer should be 0 and NOT = 10- 0
END;
MESSAGE('the Check digit is %1',CheckDigitNumber);
EXIT(CheckDigitNumber); //Return the result as an Integer.
3. After you have generated the code I recommend you convert it to text/Code so that you can combine it into a new number that is OCR compliant, e.g.
NewNumber := NumberToValidate + '' + FORMAT(CheckDigit);
MESSAGE('The new number is %1',NewNumber);
0
Comments
-
Feel free to ask any questions for clarification.0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.7K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 326 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions