Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read barcode on NADRA NIC?

Tags:

barcode

I am writing an application which reads barcode from NIC issued by NADRA (http://www.nadra.gov.pk/index.php?option=com_content&view=article&id=6&Itemid=9). NADRA issues CNIC to citizens of Pakistan. I want to read these barcode which are printed on CNIC. NADRA has encoded information like, Name, Father Name, Address, DOB etc, but these informations are stored in Urdu. I am successful in reading these Barcodes, but the thing is that, I cannot convert their characterset to Urdu. I installed urdu fonts, like Noori Nistalique, Aswad and many more, but these characterset just shows a jumble of characters, not a meaningful information. when i decode these barcode in simple english, it shows the numeric information correct, but does not show the information which is in urdu.

Have anyone tried to read these barcodes, and successfully decoded it? please help me, or guide me what I have to do...?

here is a sample which i read, this is in simple english:

A0U1200708091232 13501722 T31 2602 -E'/

here is a sample which i read and this is in Urdu:

آڑم٠٢٨٧٨٧٠١٨٠ء١٢٠٠٧٠٨٠٩١٢٣٢ ١٣٥٠١٧٢٢ ٹ٣١ص ٢٦٠٢ -فؓف ؐف-فڈف┴ف ‌،ف٩ف┴ف ‌١ف-فؐف"ففف ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌

as you can see, numeric information is same but the information which is encoded in urdu is jumbled...

any help???

like image 565
moonzai Avatar asked Nov 20 '12 12:11

moonzai


People also ask

How can I check barcode details?

Typical retail products: Indicated by a first digit of 0, 1, 6, 7, or 8. The five remaining digits on the left side of the barcode are the identify the manufacturer. The five digits on the right are the product code (determined by the manufacturer).

Can we get data from barcode?

The purpose of a barcode scanner is to scan or read a barcode symbol and then provide an electrical output to a computer via a decoder and cable. The decoder recognizes the type of barcode symbology it is seeing, translates the bar and space content and transmits data to a computer in a human readable format.

What is the CNIC number?

What is CNIC? Computerized National Identity Card (CNIC) is an identity card for Pakistani citizens living in Pakistan. Please note that CNIC and NICOP both are national ID cards. Citizen number or Nadra ID number for both cards is the same for an individual.


2 Answers

NADRA did a trick, NADRA is actually using last two characters form Hex value of a word e.g. if \u0622 is Alif (suppose) then NADRA is using only the last two characters for encoding, 22 so this is the trick only. I am attaching some code that will convert hex to Urdu, read barcode data, convert it to hex string, and then pass this string to this function, you will get all information in Urdu, just put this string in some Urdu or Arabic supported View (Android), Component (Java) or if you are using C# then put it in a Label.

public class ConvertToUrdu {

public static String convertToUrdu(String text)
{
    StringBuilder sb = new StringBuilder();

    String[] characters = text.split(",");

    for(String character : characters)
    {


        //if (ListDigits.Contains(ch))
        //{
        //    continue;
        //}
        switch (character)
        {
            case "20":
                sb.append(" ");
                break;

            case "22":
                sb.append("\u0622");
                break;

            case "27":
                sb.append("\u0627");
                break;

            case "13":
                sb.append("\u0613");
                break;

            case "28":
                sb.append("\u0628");
                break;

            case "2B":
                sb.append("\u062b");
                break;

            case "86":
                sb.append("\u0686");
                break;

            case "88":
                sb.append("\u0688");
                break;

            case "2F":
                sb.append("\u062f");
                break;

            case "10":
                sb.append("\u0610");
                break;

            case "39":
                sb.append("\u0639");
                break;

            case "41":
                sb.append("\u0641");
                break;

            case "3A":
                sb.append("\u063a");
                break;

            case "AF":
                sb.append("\u06af");
                break;

            case "2D":
                sb.append("\u062d");
                break;

            case "BE":
                sb.append("\u06be");
                break;

            case "CC":
                sb.append("\u06cc");
                break;

            case "36":
                sb.append("\u0636");
                break;

            case "2C":
                sb.append("\u062c");
                break;

            case "2E":
                sb.append("\u062e");
                break;

            case "43":
                sb.append("\u0643");
                break;

            case "12":
                sb.append("\u0612");
                break;

            case "44":
                sb.append("\u0644");
                break;

            case "45":
                sb.append("\u0645");
                break;

            case "BA":
                sb.append("\u06ba");
                break;

            case "46":
                sb.append("\u0646");
                break;

            case "29":
                sb.append("\u0629");
                break;

            case "A9":
                sb.append("\u06a9");
                break;

            case "C1":
                sb.append("\u06c1");
                break;

            //case "45":
            //    sb.Append("\u0645");
            //    break;

            case "7E":
                sb.append("\u067e");
                break;

            case "42":
                sb.append("\u0642");
                break;

            case "91":
                sb.append("\u0691");
                break;

            case "31":
                sb.append("\u0631");
                break;

            case "35":
                sb.append("\u0635");
                break;

            case "33":
                sb.append("\u0633");
                break;

            case "79":
                sb.append("\u0679");
                break;

            case "2A":
                sb.append("\u062a");
                break;

            case "21":
                sb.append("\u0621");
                break;

            case "38":
                sb.append("\u0638");
                break;

            case "37":
                sb.append("\u0637");
                break;

            //case "48":
            //    sb.Append("\\u0635\u0644\u0649\u0020\u0627\u0644\u0644\u0647\u0020\u0639\u0644\u064a\u0647\u0020\u0648\u0633\u0644\u0645");
            //    break;

            case "48":
                sb.append("\u0648");
                break;

            case "98":
                sb.append("\u0698");
                break;

            case "34":
                sb.append("\u0634");
                break;

            case "D2":
                sb.append("\u06d2");
                break;

            case "30":
                sb.append("\u0630");
                break;

            case "32":
                sb.append("\u0632");
                break;

            case "60":
                sb.append("\u0660");
                break;

            case "61":
                sb.append("\u0661");
                break;

            case "62":
                sb.append("\u0662");
                break;

            case "63":
                sb.append("\u0663");
                break;

            case "64":
                sb.append("\u0664");
                break;

            case "65":
                sb.append("\u0665");
                break;

            case "66":
                sb.append("\u0666");
                break;

            case "67":
                sb.append("\u0667");
                break;

            case "68":
                sb.append("\u0668");
                break;

            case "69":
                sb.append("\u0669");
                break;

            case "0C":
                sb.append(" \u200c");
                break;

            case "D4":
                sb.append("\u06d4");
                break;

            //case "0C":
            //    sb.Append("\u060c");
            //    break;

            case "1F":
                sb.append("\u061f");
                break;

            case "02":
                sb.append("\u0602");
                break;

            case "1B":
                sb.append("\u061b");
                break;

            case "7b":
                sb.append("\u007b");
                break;

            case "7D":
                sb.append("\u007d");
                break;
            //default:
            //    sb.Append(ch);
            //    break;
        }
    }

    return sb.toString();
}
}

I wrote this code for Java, you can convert it for any other language.

Hope for the Best :-)

NOTE
For my convenience, I added ',' after two characters in original String, so e.g. A0U1200708091232 -> A0,U1,20,07,08,09,12,32. just for debugging, so this function actually converting second string to Urdu.

EDIT
As from the comments, here is my function which is converting string to hex, I wrote this in C#

private string convertToHex(string text)
    {
        StringBuilder sb = new StringBuilder();
        foreach (char c in text)
        {
            if (c == '\n')
            {
                sb.Append('\n');
                sb.Append(',');
            }
            else
            {
                sb.Append(String.Format("{0:X}", (int)c));
                sb.Append(',');
                //sb.Append((int)c + " ");
            }
        }

        return sb.ToString();
    }

In JAVA you can convert by writing String hex = String.format("%04x", (int) c);

like image 152
moonzai Avatar answered Oct 17 '22 23:10

moonzai


In addition to the answer of @moonzai above, I would like to add some detail that I have so far able to achieve (with help of @moonzai's post off-course!).

So far, there are three types of CNIC:

  1. Regular CNIC [BarCode Encoding: PDF417]
  2. NICOP Card [BarCode Encoding: Code 128]
  3. Card with DIP Chip [BarCode Encoding: QR Code]

The latter two (2 & 3) only have ID card number and a few additional numeric details (most probably number of issues in case of (2) and Nadra_DB_# in (3))
Here is the information encoded in the PDF417 format barcode (1):

  • Receipt number (Parchi Number) which includes timestamp of your visit to NADRA’s office
  • CNIC Number
  • Family Number (Khandan Number)
  • Date of Birth
  • Full Name [Urdu]
  • Father’s Name [Urdu]
  • Full Address with District and Tehsil information [Urdu + English + Eng-Numeric]

The urdu is encoded by ommitting the common part of HEX code i.e. \u06 in case of Java/C/C++/... and "&#x6" in-case of Web or simply 0x06.
e.g. HEX code for "alif" is \u0627 or ا they only added 27 and omitted &#x6.

In case of word "جاوید" the actual string should look like: &#x62C&#x627&#x648&#x6CC&#x62F
but NADRA added only: 2C2748CC2F (ommitting all &#x6)

Appended below is a VBA code that helps generate a WEB string for scanned output of CNIC card
I will keep on adding refined code, aswell as codes in other languages; especially in JS/ Jquery and PHP.

Public Function Convert2Urdu(vString As String) As String
    Dim vCharArray As Variant, vChar As String

    For i = 1 To Len(vString)
        vChar = Mid(vString, i, 1)
        vCharArray = vCharArray & GetUrduChar(Hex(AscW(vChar)))
    Next
    Convert2Urdu = vCharArray
End Function

Private Function GetUrduChar(vHex) As String
    Select Case vHex
        ' Alphabets
        Case "22", "27", "28", "7E", "2A", "79", "2B", "2C", "86", "2D", "2E", "2F", "88", "30", "31", "91", "32", "98", "33", "34", "35", "36", "37", "38", "39", "3A", "41", "42", "A9", "AF", "44", "45", "46", "BA", "48", "C1", "C3", "BE", "21", "CC", "D2"
            GetUrduChar = "" & vHex
        ' Numerics
        Case "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F6", "F7", "F8", "F9"
            GetUrduChar = "" & vHex
        ' Eraabs
        Case "10", "11", "12", "13", "14", "15", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53", "54", "56", "57", "58", "70"
            GetUrduChar = "" & vHex
        ' Punctuation
        Case "1B", "1F", "64", "6C", "D4", "6B"
            GetUrduChar = "" & vHex
        ' Space
        Case "20"
            GetUrduChar = "" & "0" & vHex
        Case Else
           GetUrduChar = " " & Chr(vHex) & " " ' Ideally, it should be Chr(Asc(Hex)) [working on it]
    End Select
End Function
like image 35
Khaled Javeed Avatar answered Oct 17 '22 23:10

Khaled Javeed