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.6K 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
- 320 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