Search This Blog

Title of the confirm dialog

Description of what is about to happen

Showing posts with label validation. Show all posts
Showing posts with label validation. 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

Validasi NPWP


Nomor Pokok Wajib Pajak (Indonesia)

Kartu NPWP memiliki kode seri dengan 15 (lima belas) angka, yang menggunakan format seperti berikut: 99.999.999.9-999.999.


Dua(2) digit pertama, 99.999.999.9-999.999 menunjukkan Identitas Wajib Pajak, yaitu:
○ 01 sampai 03 adalah Wajib Pajak Badan
○ 04 dan 06 adalah Wajib Pajak Pengusaha
○ 05 adalah Wajib Pajak Karyawan
○ 07 sampai 09 adalah Wajib Pajak Orang Pribadi


Enam(6) digit berikut, 99.999.999.9-999.999 menunjukkan Nomor Registrasi / Urut yang diberikan Kantor Pusat Direktorat Jenderal Pajak kepada Kantor Pelayanan Pajak (KPP).

Satu(1) digit berikutnya 99.999.999.9-999.999 berfungsi sebagai alat pengaman untuk menghindari terjadinya pemalsuan atau kesalahan pada NPWP.

Tiga(3) digit berikut, 99.999.999.9-999.999 adalah Kode KPP, contohnya 001, berarti NPWP tersebut dikeluarkan di KPP Pratama Jakarta Matraman.

Tiga digit terakhir, 99.999.999.9-999.999 menunjukkan Status Wajib Pajak:
○ 000 berarti Tunggal atau Pusat
○ 00x (001,002 dst) berarti Cabang, dimana angka akhir menunjukkan urutan cabang (cabang ke-1 maka 001, cabang ke-2 maka 002, dst.).


Langkah Validasi

NPWP#: 12.345.678.x-123.000
Data untuk proses validasi: 12345678123000 (hanya angka tanpa tanda titik “.” ataupun strip “-” )

Langkah-langkah untuk validasi kode seri NPWP adalah sebagai berikut:
1.Gunakan 8 digit angka awal dari NPWP => 12345678.
2.Kalikan digit ganjil dengan 1 dan digit genap dengan angka 2.
3.Jumlahkan masing-masing hasilnya, untuk hasil bilangan dengan 2 digit perlakukan sebagai dua buah bilangan, 1+4+3+8+5+1+2+7+1+6=38
4.Lakukan pembulatan ke atas ke bilangan puluhan terdekat, 38 => 40
5.Digit ke-9 NPWP (x) adalah hasil langkah ke-4 dikurangi dengan hasil langkah ke-3, x=40–38=2
Penghitungan:
8 digit awal 1 2 3 4 5 6 7 8
ganjil x1, genap x2 1 4 3 8 5 12 7 16
hitung, >9 jadi dua angka 1 4 3 8 5 1+2 7 1+6
hitung, >9 jadi dua angka 1 4 3 8 5 3 7 7
total pembulatan puluhan keatas 38 -> 40 - 38 = 2

Sehingga NPWP yang benar adalah 12.345.678.2-123.000

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 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; // .Net FrameWork 4.0
 
namespace TechScale
{
    public static class NPWP
    {
        /// <summary>
        /// return logical validity of npwp
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        internal static bool IsValid(string arg)
        {
            var dat = arg.Where(w => w >= '0' && w <= '9'); if (dat.Count() != 15) { return false; }
            var f08 = dat.Take(8);
            var h08 = f08.Select((s, i) => { return CharsSum(s, i); }).Sum();
            var d09 = h08 % 10 == 0 ? h08 : ((int)Math.Ceiling(h08 / 10d)) * 10; d09 -= h08;
            var val = string.Concat(
                      string.Concat(f08), d09,
                      string.Concat(dat.Select((s, i) => { return i >= 9 ? s.ToString() : ""; })));
            return val == string.Concat(dat);
        }
        /// <summary>
        /// valid npwp digit #9
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        internal static int ValidCheckCode(string arg)
        {
            var dat = arg.Where(w => w >= '0' && w <= '9'); if (dat.Count() < 8) { return -1; }
            var f08 = dat
                      .Take(8)
                      .Select((s, i) => { return CharsSum(s, i); })
                      .Sum();
            var d09 = f08 % 10 == 0 ? f08 : ((int)Math.Ceiling(f08 / 10m)) * 10; d09 -= f08;
            return d09;
        }
        private static int CharsSum(int s, int i)
        {
            var res = (s - 48) * (i % 2 == 0 ? 1 : 2);
            return
                res > 9 ?
                res.ToString().Select(n => Convert.ToInt32(n.ToString())).Sum() :
                res;
        }
    }
}

Test

Immediate Window
?NPWP.IsValid("12.345.678.2-123.000")
 true
?NPWP.ValidCheckCode("12345678")
 2

varyes = NPWP.IsValid("12.345.678.2-123.000"); // return true vardgt = NPWP.ValidCheckCode("12345678"); // return 2

TOP

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

Shipping Container Code Validation

Derivated from ISO 6346

ISO 6346 is an international standard covering the coding, identification and marking of intermodal (shipping) containers used within containerized intermodal freight transport. The standard establishes a visual identification system for every container
that includes a unique serial number (with check digit), the owner, a country code, a size, type and equipment category as well as any operational marks. The standard is managed by the International Container Bureau (BIC).
(ref https:s://en.wikipedia.org/wiki/ISO_6346)


Container Code Format ISO6346

Format AAAX0000009
AAA Owner Code
The owner code consists of three capital letters of the Latin alphabet to indicate the owner or principal operator of the container. Such code needs to be registered at the Bureau International des Conteneurs in Paris to ensure uniqueness worldwide.
X Equipment Category Identifier
The equipment category identifier consists of one of the following capital letters of the Latin alphabet:
J : detachable freight container-related equipment
U : freight containers
Z : trailers and chassis
Under the ISO code, then, only J, U and Z are in use—the reefer container is identified by means of the size type code.
000000
Serial Number
The serial number consists of 6 numeric digits, assigned by the owner or operator, uniquely identifying the container within that owner/operator's fleet.
9
Check Digit
The check digit consists of one numeric digit providing a means of validating the recording and transmission accuracies of the owner code and serial number.


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 ContainerCodeValidation
    {
        /// <summary>
        /// check alphanumeric container code, 
        /// code4: 
        /// J = EQUIPMENTS &amp; TOOLS,
        /// U = Universal,
        /// Z = CHASSIS &amp; TRAILER
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static string GetCheckDigitContainerID(this string arg)
        {
            if (string.IsNullOrWhiteSpace(arg))
                return string.Concat(arg, "☺");
            // remove space, make uppercase
            var id = arg.Trim().Replace(" ", string.Empty).ToUpper();
            // make 10 chars or take 10 chars
            id = id.Length < 10 ? 
                 id.PadRight(10, '0') : 
                 (id.Length > 10 ? id.Substring(0, 10) : id);
            // alphabet, numeric and space only
            foreach (var s in id)
            {
                 if (!"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789".Contains(s)) 
                     return arg; 
            }
            // valid code position 4th
            var code4 = "JUZ";
            for (var c = 0; c < "AAAX".Length; c++)
            {
                if (c < 3 && 
                    !"ABCDEFGHIJKLMNOPQRSTUVWXYZ".Contains(id[c]))
                    return arg;
                if (c == 3 && !code4.Contains(id[c])) return arg; 
            }
            for (var c = 0; c < 10; c++) 
            { if (!"0123456789".Contains(id[c]))  return arg; }
            int numer = 0, azFrom = 10, azTo = 39;
            var codAZ = Enumerable.Range(azFrom, (azTo - azFrom))
                        .Where(n => n % 11 > 0 && n <= azTo)
                        .ToArray();
            var multi = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
            var codes = new List<int>();
            try
            {
                var i = 0;
                foreach (var s in id)
                {
                    numer = 0; 
                    if (i < 4) { numer = codAZ[(int)s - 65]; } 
                    else { int.TryParse(s.ToString(), out numer); }
                    numer *= multi[i]; codes.Add(numer);
                    i++;
                }
                numer = codes.Sum();
                numer -= (int)Math.Floor(numer / 11d) * 11;
                id = string.Concat(id, " ", numer);
            }
            catch { id = string.Concat(id, "-1"); }
            codAZ = null; multi = null; codes.Clear(); codes = null;
            return id;
        }
        /// <summary>
        /// extension: containe code validation
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static bool IsValidContainerCode(this string arg)
        {
            var ret = ""; return IsValidContainerCode(arg, ref ret);
        }
        /// <summary>
        /// extension: containe code validation
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="result">filtered string</param>
        /// <returns></returns>
        public static bool IsValidContainerCode(
               this string arg, ref string result)
        {
            var valid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            // check valid string, check string length must be 11 
            var v0 = string.Join(string.Empty, 
                     // make uppercase
                     arg.ToUpper()
                     // remove empty char
                     .Replace(" ", string.Empty)
                     // alphabet and numeric only
                     .Where(f => valid.Contains(f))
                     // as array for string.join purpose
                     .ToArray()); if (v0.Length != 11) { return false; }
            // do checking methode, get result
            var v1 = v0.GetCheckDigitContainerID().Replace(" ", ""); 
            result = v0;
            return v0 == v1;
        }
    }
}


Test

Immediate Window
?"CSQU3054383".IsValidContainerCode()
 true

bool yes = "CSQU3054383".IsValidContainerCode(); // return true

TOP   ISO6346 Live Validation