Search code examples
barcode

How to read barcode on NADRA NIC?


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???


Solution

  • 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);