Search This Blog

Title of the confirm dialog

Description of what is about to happen

Showing posts with label card. Show all posts
Showing posts with label card. Show all posts

Payment Card Number Validation


A payment card is a device that enables its owner (the cardholder) to make a payment by electronic funds transfer. The most common types of payment cards are credit cards and debit cards. Payment cards are usually embossed plastic cards, 85.60 × 53.98 mm in size, which comply with the ISO/IEC 7810 ID-1 standard. They usually also have an embossed card number conforming with the ISO/IEC 7812 numbering standard.

ref: https://en.wikipedia.org/wiki/Payment_card

Today there are many types of cards (payment / credit), there is one of simple way to test the card number, whether valid / invalid, using the Luhn algorithm. Matching publisher network can also be done if it had known the data of the card's issuer networking.




What goal?
○ Check/validate Card Number based on Luhn Algorithm.
○ Check Type, Issuer, Active.
○ Random Card Number Generator Simulation.
○ For Learning Purpose.



Main Class for PayCard Checker

Source Code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; // .Net Framework 4.0

namespace TechScales
{ 
    internal class PayCardEngine
    {
        ~PaymentCardEngine()
        {
            if (Cards != null && Cards.Count > 0) { Cards.Clear(); Cards = null; }
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        internal enum CardType
        {
            Unidentify = -1,
            AmericanExpress = 0,
            Bankcard,
            ChinaUnionPay,
            DinersClubCarteBlanche,
            DinersClubenRoute,
            DinersClubInternational,
            DinersClubUSA_Canada,
            DiscoverCard,
            InterPayment,
            InstaPayment,
            JCB,
            Laser,
            Maestro,
            Dankort,
            NSPKMIR,
            MasterCard,
            Solo,
            Switch,
            Visa,
            UATP,
            Verve,
            CardguardEadbGils,
        }
        internal enum Active
        {
            Undefined = -1,
            No = 0,
            Yes = 1,
        }
        internal enum Checker
        {
            None = 0,
            Luhn = 1,
        }
        internal class ValidThrough
        {
            public ValidThrough(int month, int year)
            {
                Month = month; Year = year;
            }
            public int Month
            {
                get;
                set;
            }
            public int Year
            {
                get;
                set;
            }
            public override string ToString()
            {
                return string.Concat(Month, "/", (Year % 1000));
            }
        }
        internal static void ResetCardsData()
        {
            if (Cards != null)
            {
                Cards.Clear(); Cards = null;
            }
            Cards = new List<PayCard>();
        }
        static List<PayCard> Cards { get; set; }

        internal class PayCard
        {
        }
    }
}

Card Type, can be added within enum PayCardEngine.CardType after line41. Card Type also can be taken uniquely from added card data network. Class PayCard will described in here.

Top    Payment Card Live Validation

Luhn Algorithm


Known as the "modulus 10" or "mod 10" algorithm, is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, National Provider Identifier numbers in the US, and Canadian Social Insurance
Numbers. It was created by IBM scientist Hans Peter Luhn and described in U.S. Patent No. 2,950,048, filed on January 6, 1954, and granted on August 23, 1960.

(ref https://en.wikipedia.org/wiki/Luhn_algorithm)


Source Code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105 
106
107
108 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; // .Net Framework 4.0


namespace TechScales
{
    internal static class Luhn
    {
        /// <summary>
        /// Luhn Algoritm.
        /// </summary>
        /// <param name="numbers">numbers to check</param> 
        internal static bool IsValid(string numbers)
        {
            int len = numbers.Length;
            int dgt = 0, sum = 0;
            int pos = 0; //the current process number (to calc odd/even proc)
            for (int i = len - 1; i >= 0; i--)
            {
                //digit on right most
                string rgt = numbers.Substring(i, 1);
                //parse 
                if (!int.TryParse(rgt, out dgt)) { return false; }
                //double value of every 2nd right most
                //if value = 2digits, sum the digits by substract by 9
                if (pos % 2 != 0) { if ((dgt *= 2) > 9) { dgt -= 9; } }
                //increase the proc number
                pos++;
                //summarize the processed digits
                sum += dgt;
            }
            //if sum is divisible by 10, return valid, else notValid
            return (sum % 10 == 0);
        }

        /// <summary>
        /// Luhn Algoritm.
        /// </summary>
        /// <param name="sidNum">numbers to check</param> 
        internal static bool IsValidA(string numbers)
        {
            int sum = 0, pos = 0;
            // select numeric only
            // reverse collection, need to sumarize from right most
            var num = numbers.Where(c => "0123456789".Contains(c)).Reverse();
            foreach(var n in num)
            {
                // multiply by 2 of every even digit value.
                // if digit value > 9, substract it by 9.
                // perform addition  
                var i = n - 48;
                sum += pos % 2 != 0 ? ((i *= 2) > 9 ? (i - 9) : i) : i;
                // next digit
                pos++;
            };
            return sum % 10 == 0;
        }

        /// <summary>
        /// extension: verify string by Luhn algorithm
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        internal static bool IsLuhnVerified(this string arg)
        {
            return !string.IsNullOrWhiteSpace(arg) ? IsValidA(arg) : false;
        }

        /// <summary>
        /// extension: verify numbers by Luhn algorithm
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        internal static bool IsLuhnVerified(this long arg)
        {
            return
                !string.IsNullOrWhiteSpace(arg.ToString()) ?
                IsValidA(arg.ToString()) : false;
        }

        /// <summary>
        /// get valid check digit of complete string numbers
        /// using Luhn algorithm<para></para>
        /// string cannot be empty/null value
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="numOnly">get number only</param>
        /// <returns></returns>
        internal static int ValidCheckDigit(string arg, bool numOnly = false)
        {
            int sum = 0, pos = 0;
            var num = (!numOnly ? 
                      arg : 
                      arg.Where(c => "0123456789".Contains(c)))
                      .Reverse();
            foreach (var n in num)
            {
                var i = n - 48;
                sum += pos % 2 == 0 ? ((i *= 2) > 9 ? (i - 9) : i) : i;
                pos++;
            }
            return ((int)Math.Ceiling(sum / 10d) * 10) - sum;
        }
    }
}


Test

Immediate Window
?Luhn.IsValidA("4987 6532 1012 3456")
 true
?NPWP.ValidCheckCode("12345678")
 2

var yes = Luhn.IsValidA("4987 6532 1012 3456"); // return true var dgt = Luhn.ValidCheckDigit("4987 6532 1012 345"); // return 6


TOP