Recently we came across an interesting problem of credit card theft and as part of the investigation we found tons of digits which matches the pattern of the credit card. After finding that bunch of data it was difficult to report the correct numbers. Any random number of 16 digits or 15 digits and so on can be either a credit card or some identifier or some dummy number into the system. The problem was really interesting.
After some research on web we found that most of the credit cards companies rather than generating any random number uses some algorithms to generate the number. Luhn test is one of the widely accepted algorithm to distinguish the credit card number. The below mentioned steps and SQL Code can be used to validate a credit card number. We are taking 49927398716 number as an example for the below steps.
Luhn’s Test:
- Get the credit card number. For our example we are assuming 49927398716 as the given number.
- Reverse the digits of the given number. For our example it will become like 61789372994.
- Take the sum of all the odd digits in the reversed number. Which is as 6 + 7 + 9 + 7 + 9 + 4 = 42.
- Take all the even digits. E.g. 1, 8, 3, 2, 9 and multiply each one of them with two. For our example the digits will become like 2, 16, 6, 4, 18.
- Wherever the number is greater than nine sum the digits of the number to make it a single digit number. The number s in step 4 will become like 2, 7, 6, 4, 9.
- Sum the numbers in the step 5. E.g. 2 + 7 + 6 + 4 + 9 = 28.
- Now sum the number in the step 3 and step 6. E.g. 28 + 42 = 70
- If the sum ends in zero then it can be a valid credit card number. In other words if the remainder of the Step 7 divided by 10 is zero than it can be a valid credit card number. So in our case 70%10 = 0 and hence it can be a valid credit card number.
Sample SQL Code for Luhn’s Test:
Here we have created a T-SQL function to verify the above test but it can be implemented in any other manner as well.
DECLARE
@cardNo NVARCHAR(20) = '49927398716'
,@reverseCardNo NVARCHAR(20)
,@sum SMALLINT
,@number SMALLINT
,@counter SMALLINT
SELECT
@cardNo = LTRIM(RTRIM(@cardNo))
,@reverseCardNo = REVERSE(@cardNo)
,@sum = 0
,@counter = 1
WHILE(@counter <=
LEN(@cardNo))
BEGIN
SELECT
@number
= TRY_CONVERT(SMALLINT, LEFT(@reverseCardNo, 1))
IF(@counter%2 = 0) --EVEN NUMBER
BEGIN
SELECT
@number
*= 2
IF (LEN(@number) > 1)
BEGIN
SELECT
@number
= TRY_CONVERT(SMALLINT, LEFT(@number, 1)) + TRY_CONVERT(SMALLINT, RIGHT(@number, 1))
END
END
SELECT
@sum += @number
,@counter += 1
,@reverseCardNo = RIGHT(@reverseCardNo, LEN(@reverseCardNo)-1)
END
IF(@sum >
0 AND @sum%10 = 0)
PRINT CONCAT('Test passed. ', @cardNo, ' can be a potential card number.')
ELSE
PRINT CONCAT('Test failed. ', @cardNo, ' invalid card number.')
|