阅读Mifare Classic会返回奇怪的字符 [英] Reading Mifare Classic returns strange characters

查看:118
本文介绍了阅读Mifare Classic会返回奇怪的字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用Android读取MIFARE卡并将数据转换为UTF-8时,会出现类似 的奇怪字符. 我正在尝试构建一个可以读取我们正在使用的身份证的应用程序.现在的问题是,我在单词之间出现了奇怪的字符,并且某些单词在块之间被拆分,因此如何安全地找到要查找的单词? 例如我的读物是这样的:

When reading a MIFARE card with Android and converting the data to UTF-8 I get strange characters like �. I'm trying to build an application that can read some kind of ID card we're using. The problem now is that I get weird characters between words and some words are split between blocks so how can I safely get a word I'm looking for? For instance my readings is something like this:

43224 19032019 在块2 sektor 2 bindex:8

43224���19032019�� at block 2 sektor 2 bindex :8

并进行拆分,其中以19开头的数字的其余部分位于一个新的块上:

and with splitting where rest of the number starting with 19 is at a new block:

.我的名字 M 19

�me Name���M���19

在第1区sektor 1 bindex:4

at block 1 sektor 1 bindex :4

930402 NO934951

930402���NO934951

在第2区块sektor 1 bindex:4

at block 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循环内阅读的代码:

Here is my code I use for reading inside a for loop:

 data = mfc.readBlock(bIndex + block); 

然后将数据转换为UTF8以进行打印,我使用:

and then for converting data to UTF8 for printing I use:

   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等运气不佳.

I've tried with ASCII, UTF-16 etc with no luck.

推荐答案

因此,标签上的数据(不包括扇区尾部)看起来像这样:

So the data on your tag (excluding the sector trailers looks somewhat like that:


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

这似乎是某种形式的结构化数据.简单地将整个二进制Blob转换为UTF-8(或ASCII)编码的字符串没有多大意义.相反,您将需要对数据的结构方式进行逆向工程(或者,甚至更好的是,您尝试从系统制造商那里获取规范).

This seems to be some form of structured data. Simply converting the whole binary blob into a UTF-8 (or ASCII) encoded string doesn't make much sense. Instead, you will need to reverse engineer the way that the data is structured (or, even better, you try to obtain the specification from the system manufacturer).

据我所见,数据看起来好像是由多个以空值结尾的字符串组成的,这些字符串以某种紧凑的(Tag)-Length-Value格式嵌入.第一个字节似乎是tag(?)+长度,所以我们有

From what I can see, it looks as if that data consisted of multiple null-terminated strings embedded into some compact (Tag)-Length-Value format. The first byte seems to be the tag(?) + length, so we have


C5    Length = 5
    42 4E 49 44 00                                               "BNID"
07    Length = 7
    4F 4F 4F 4F 4F 4F 00                                         "OOOOOO"
4B    Length = 11
    42 44 44 44 20 44 44 44 44 44 00                             "KBDDD DDDDD"
82    Length = 2
    4D 00                                                        "M"
C9    Length = 9
    31 39 39 34 34 33 34 32 00                                   "19944342"
D0    Length = 16
    4E 4F 39 36 36 36 35 31 30 32 32 20 20 41 53 00              "NO966651022  AS"
D3    Length = 19
    54 4F 54 41 4C 20 4B 4F 4E 54 52 4F 4C 4C 20 41 53 20 00     "TOTAL KONTROLL AS "
C9    Length = 9
    30 32 38 37 30 34 33 33 00                                   "02870433"
C9    Length = 9
    32 30 32 31 30 32 31 31 00                                   "20210211"

例如,可以将第一个字节划分为标签和长度,如下所示:TTTL LLLL(高3位编码标签,低5位编码后续值的长度).这将给出以下标签

The first byte could, for instance, be split into tag and length like this: TTTL LLLL (upper 3 bits encode the tag, lower 5 bits encode the length of the following value). This would give the following tags

  • 0x6表示"BNID","19944342","NO966651022 AS","TOTAL KONTROLL AS","02870433"和"20210211"
  • 0x0代表"OOOOOO"
  • 0x2代表"KBDDD DDDDD"
  • 0x4代表"M"
  • 0x6 for "BNID", "19944342", "NO966651022 AS", "TOTAL KONTROLL AS ", "02870433", and "20210211"
  • 0x0 for "OOOOOO"
  • 0x2 for "KBDDD DDDDD"
  • 0x4 for "M"

因此,标记和长度之间的距离也可能是TTLL ​​LLLL(标记的高2位编码,标记后面的值的长度低6位).

Hence, the split between tag and length might also be TTLL LLLL (upper 2 bits encode the tag, lower 6 bits encode the length of the following value).

不幸的是,该格式与我所知道的任何流行格式都不相似.因此,您可以通过比较多个不同的卡并从值中得出含义来继续进行逆向工程.

Unfortunately, the format doesn't resemble any of the popular formats that I'm aware of. So you could just continue your reverse engineering by comparing multiple different cards and by deriving meaning from the values.

到目前为止,为了解码上述内容,您将从读取第一个字节开始,从该字节中提取长度,减少后续字节的数量,然后将其转换为字符串(基于您所采样的示例)提供,则应使用ASCII编码).然后,您可以继续下一个字节,从中提取长度信息,...

So far, in order to decode the above, you would start by reading the first byte, extract the length from that byte, cut that amount of follow-up bytes and convert them into a string (based on the sample that you provided, ASCII encoding should do). You can then continue with the next byte, extract the length information from it, ...

这篇关于阅读Mifare Classic会返回奇怪的字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆