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???
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).
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 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.
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);
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:
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):
The urdu is encoded by ommitting the common part of HEX code i.e. \u06 in case of Java/C/C++/... and "" in-case of Web or simply 0x06.
e.g. HEX code for "alif" is \u0627 or ا they only added 27 and omitted .
In case of word "جاوید" the actual string should look like: جاوید
but NADRA added only: 2C2748CC2F (ommitting all )
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With