当使用Android读取MIFARE卡并将数据转换为UTF-8时,会出现奇怪的字符。
我正在尝试构建一个可以读取我们正在使用的身份证的应用程序。现在的问题是,我在单词之间出现了奇怪的字符,并且某些单词在块之间被拆分,因此如何安全地找到要查找的单词?
例如我的阅读是这样的:
43224���19032019��
在块2 sektor 2 bindex:8
并进行分割,其中以19开头的数字的其余部分位于新的块:
我的名字M 19
在块1 sektor 1 bindex:4
930402.��NO934951
在块2 sektor 1 bindex:4
c5 42 4e 49 44 00 07 4f 4f 4f 4f 4f 4f 00 4b 42 "Åbnid" "OOOOOO" "KB" 44 44 44 20 44 44 44 44 44 00 82 4d 00 c9 31 39 "DDD DDDDD" "M" "19" 39 34 34 33 34 32 00 d0 4e 4f 39 36 36 36 35 31 "944342" "NO966651" 00 00 00 00 00 00 70 f7 88 00 00 00 00 00 00 00 30 32 32 20 20 41 53 00 d3 54 4f 54 41 4c 20 4b "022" "AS" "Total k" 4f 4e 54 52 4f 4c 4c 20 41 53 20 00 c9 30 32 38 "ONTROLL AS" "028" 37 30 34 33 33 00 c9 32 30 32 31 30 32 31 31 00 "70433" "20210211" 00 00 00 00 00 00 70 f7 88 00 00 00 00 00 00 00
This is how I read from the card:
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareClassic mfc = MifareClassic.get(tagFromIntent);
这是我用于在for循环内阅读的代码:
data = mfc.readBlock(bIndex + block);
然后将数据转换为UTF8以进行打印,我使用:
public String convertByteArrayToUTF8(byte[] bytes){
String encoded = null;
try {
encoded = new String(bytes, StandardCharsets.UTF_8);
}
catch (Exception e){
encoded = new String(bytes, Charset.defaultCharset());
}
return encoded;
}
我尝试过ASCII,UTF-16等,但没有运气。
最佳答案
因此,标签上的数据(不包括扇区尾部)看起来像这样:
C5 42 4E 49 44 00 07 4F 4F 4F 4F 4F 4F 00 4B 42ÅBNID..OOOOOO.KB
44 44 44 20 44 44 44 44 44 00 82 4D 00 C9 31 39 DDD DDDDD.‚M.É19
39 34 34 33 34 32 00 D0 4E 4F 39 36 36 36 35 31944342.ÐNO966651
30 32 32 20 20 41 53 00 D3 54 4F 54 41 4C 20 4B 022AS.ÓTOTALK
4F 4E 54 52 4F 4C 4C 20 41 53 20 00 C9 30 32 38 ONTROLL AS.É028
37 30 34 33 33 00 C9 32 30 32 31 30 32 31 31 0070433.É20210211。
这似乎是某种形式的结构化数据。简单地将整个二进制Blob转换为UTF-8(或ASCII)编码的字符串没有多大意义。相反,您将需要对数据的结构方式进行逆向工程(或者,甚至更好的是,您尝试从系统制造商那里获取规范)。
从我所看到的来看,数据看起来好像是由多个以空值结尾的字符串组成,这些字符串以某种紧凑的(Tag)-Length-Value格式嵌入。第一个字节似乎是tag(?)+长度,所以我们有
C5长度= 5
42 4E 49 44 00“ BNID”
07长度= 7
4F 4F 4F 4F 4F 4F 4F 00“ OOOOOO”
4B长度= 11
42 44 44 44 20 44 44 44 44 44 00“ KBDDD DDDDD”
82长度= 2
4D 00“ M”
C9长度= 9
31 39 39 34 34 33 34 32 00“ 19944342”
D0长度= 16
4E 4F 39 36 36 36 35 31 30 32 32 20 20 41 53 00“ NO966651022 AS”
D3长度= 19
54 4F 54 41 4C 20 4B 4F 4E 54 52 4F 4C 4C 20 41 53 20 00“总KONTROLL AS”
C9长度= 9
30 32 38 37 30 34 33 33 00“ 02870433”
C9长度= 9
32 30 32 31 30 32 31 31 00“ 20210211”
例如,可以将第一个字节拆分为标签和长度,如下所示:TTTL LLLL(高3位编码标签,低5位编码后续值的长度)。这将给出以下标签0x6
代表“ BNID”,“ 19944342”,“ NO966651022 AS”,“ TOTAL KONTROLL AS”,“ 02870433”和“ 20210211”0x0
代表“ OOOOOO”0x2
代表“ KBDDD DDDDD”0x4
代表“ M”
因此,标签和长度之间的划分也可能是TTLL LLLL(高2位编码标签,低6位编码后续值的长度)。
不幸的是,这种格式与我所知道的任何流行格式都不相似。因此,您可以通过比较多个不同的卡并从值中得出含义来继续进行逆向工程。
到目前为止,为了解码上述内容,您将从读取第一个字节开始,从该字节中提取长度,减少后续字节的数量,然后将它们转换为字符串(基于您提供的示例,ASCII)编码即可)。然后,您可以继续下一个字节,从中提取长度信息,...