6

我正在编写一个从 NADRA (http://www.nadra.gov.pk/index.php?option=com_content&view=article&id=6&Itemid=9) 发布的 NIC 读取条形码的应用程序。NADRA 向巴基斯坦公民发放 CNIC。我想阅读打印在 CNIC 上的这些条形码。NADRA 已编码信息,如姓名、父亲姓名、地址、出生日期等,但这些信息存储在乌尔都语中。我成功阅读了这些条形码,但问题是,我无法将它们的字符集转换为乌尔都语。我安装了 urdu 字体,比如 Noori Nistalique、Aswad 等等,但是这些字符集只是显示了一堆乱七八糟的字符,而不是有意义的信息。当我用简单的英文解码这些条形码时,它显示数字信息正确,但不显示乌尔都语中的信息。

有没有人尝试读取这些条形码并成功解码?请帮助我,或指导我该怎么做...?

这是我阅读的一个示例,这是简单的英语:

A0U1200708091232 13501722 T31 2602 -E'/

这是我读过的一个样本,这是乌尔都语:

آڑم0287870180ء120070809123213501722ٹ1111ص2602-فففڈف┴ف,ف9ف┴ف1ف-فف“ففف</ p>

如您所见,数字信息是相同的,但以乌尔都语编码的信息是混乱的......

有什么帮助吗???

4

2 回答 2

7

NADRA 做了一个技巧,NADRA 实际上是使用最后两个字符形成一个单词的十六进制值,例如如果\u0622是 Alif(假设)那么 NADRA 只使用最后两个字符进行编码,22所以这只是技巧。我附上了一些将十六进制转换为乌尔都语的代码,读取条形码数据,将其转换为十六进制字符串,然后将此字符串传递给此函数,您将获得乌尔都语中的所有信息,只需将此字符串放入某些乌尔都语或阿拉伯语支持的视图中(Android)、组件 (Java) 或者如果您使用的是 C#,则将其放入标签中。

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();
}
}

我为 Java 编写了这段代码,您可以将其转换为任何其他语言。

希望最好的 :-)

注意
为了方便起见,我在原始字符串的两个字符之后添加了 ',',例如 A0U1200708091232-> A0,U1,20,07,08,09,12,32。只是为了调试,所以这个函数实际上将第二个字符串转换为乌尔都语。

编辑
从评论中,这是我将字符串转换为十六进制的函数,我用 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();
    }

在 JAVA 中,您可以通过编写转换String hex = String.format("%04x", (int) c);

于 2014-04-30T09:10:28.027 回答
2

除了上面@moonzai 的答案之外,我想添加一些我迄今为止能够实现的细节(在@moonzai 的帖子的帮助下!)。

到目前为止,共有三种类型的 CNIC:

  1. 常规 CNIC [条形码编码:PDF417]
  2. NICOP 卡 [条形码编码:代码 128]
  3. 带 DIP 芯片的卡 [条形码编码:二维码]

后两者(2 和 3)只有身份证号和一些额外的数字细节(很可能是(2)和 Nadra_DB_# 中的问题数量(3))
这是以 PDF417 格式条形码编码的信息( 1):

  • 收据编号(Parchi 编号),其中包括您访问 NADRA 办公室的时间戳
  • CNIC 编号
  • 家庭号码(Khandan 号码)
  • 出生日期
  • 全名 [乌尔都语]
  • 父亲的名字 [乌尔都语]
  • 带有地区和 Tehsil 信息的完整地址 [乌尔都语 + 英语 + 英语-数字]

urdu 是通过省略 HEX 代码的公共部分来编码的,即在 Java/C/C++/... 的情况下为 \u06,在 Web 的情况下为“”或简单的 0x06。
例如,“alif”的十六进制代码是 \u0627 或 ا 他们只添加了 27 并省略了 。

如果是单词“جاوید”,实际字符串应如下所示:جاوید
但仅添加了 NADRA:2C2748CC2F (省略所有 )

下面附加的是有助于生成 WEB 字符串的 VBA 代码对于CNIC卡的扫描输出,
我将继续添加精炼代码,以及其他语言的代码;特别是在 JS/Jquery 和 PHP 中。

公共函数 Convert2Urdu(vString As String) As String
    将 vCharArray 调暗为 Variant,将 vChar 调暗为字符串

    For i = 1 To Len(vString)
        vChar = Mid(vString, i, 1)
        vCharArray = vCharArray & GetUrduChar(Hex(AscW(vChar)))
    下一个
    Convert2Urdu = vCharArray
结束功能

私有函数 GetUrduChar(vHex) 作为字符串
    选择案例 vHex
        ' 字母
        案例“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
        ' 数字
        案例“F0”、“F1”、“F2”、“F3”、“F4”、“F5”、“F6”、“F6”、“F7”、“F8”、“F9”
            GetUrduChar = " " & vHex
        '伊拉布斯
        案例“10”、“11”、“12”、“13”、“14”、“15”、“4B”、“4C”、“4D”、“4E”、“4F”、“50”、“ 51”、“52”、“53”、“54”、“56”、“57”、“58”、“70”
            GetUrduChar = " " & vHex
        ' 标点符号
        案例“1B”、“1F”、“64”、“6C”、“D4”、“6B”
            GetUrduChar = " " & vHex
        ' 空间
        案例“20”
            GetUrduChar = "&#x" & "0" & vHex
        其他情况
           GetUrduChar = " " & Chr(vHex) & " " ' 理想情况下,它应该是 Chr(Asc(Hex)) [正在处理]
    结束选择
结束功能
于 2014-05-06T16:23:43.573 回答