問題描述
在使用 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 0030 32 32 20 20 41 53 00 d3 54 4f 54 41 4c 20 4b 022" AS" 總 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這是我從卡片中讀取的方式:
標簽 tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);MifareClassic mfc = MifareClassic.get(tagFromIntent);
這是我用于在 for 循環中讀取的代碼:
data = mfc.readBlock(bIndex + block);
然后我使用將數據轉換為 UTF8 進行打印:
public String convertByteArrayToUTF8(byte[] bytes){字符串編碼 = null;嘗試 {編碼 = 新字符串(字節,StandardCharsets.UTF_8);}捕獲(異常 e){編碼=新字符串(字節,Charset.defaultCharset());}返回編碼;}
我嘗試過使用 ASCII、UTF-16 等,但沒有成功.
所以你標簽上的數據(不包括扇區預告片看起來有點像:
<上一頁>C5 42 4E 49 44 00 07 4F 4F 4F 4F 4F 4F 00 4B 42 ?BNID..OOOOOO.KB44 44 44 20 44 44 44 44 44 00 82 4D 00 C9 31 39 DDD DDDDD.,M.é1939 34 34 33 34 32 00 D0 4E 4F 39 36 36 36 35 31 944342.DNO96665130 32 32 20 20 41 53 00 D3 54 4F 54 41 4C 20 4B 022 AS.óTOTAL K4F 4E 54 52 4F 4C 4C 20 41 53 20 00 C9 30 32 38 ONTROLL AS .é02837 30 34 33 33 00 C9 32 30 32 31 30 32 31 31 00 70433.é20210211.這似乎是某種形式的結構化數據.簡單地將整個二進制 blob 轉換為 UTF-8(或 ASCII)編碼的字符串沒有多大意義.相反,您需要對數據的結構方式進行逆向工程(或者,更好的是,您嘗試從系統制造商處獲取規范).
據我所見,該數據似乎由多個以空字符結尾的字符串組成,這些字符串嵌入到某種緊湊的 (Tag)-Length-Value 格式中.第一個字節似乎是標簽(?)+長度,所以我們有
<上一頁>C5 長度 = 542 4E 49 44 00 BNID"07 長度 = 74F 4F 4F 4F 4F 4F 00 OOOOOO"4B 長度 = 1142 44 44 44 20 44 44 44 44 44 00 KBDDD DDDDD"82 長度 = 24D 00M"C9 長度 = 931 39 39 34 34 33 34 32 00 19944342"D0 長度 = 164E 4F 39 36 36 36 35 31 30 32 32 20 20 41 53 00 NO966651022 AS"D3 長度 = 1954 4F 54 41 4C 20 4B 4F 4E 54 52 4F 4C 4C 20 41 53 20 00 TOTAL KONTROLL AS"C9 長度 = 930 32 38 37 30 34 33 33 00 02870433"C9 長度 = 932 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編碼應該做).然后您可以繼續下一個字節,從中提取長度信息,...
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?? at block 2 sektor 2 bindex :8
and with splitting where rest of the number starting with 19 is at a new block:
?me Name???M???19
at block 1 sektor 1 bindex :4
930402???NO934951
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);
Here is my code I use for reading inside a for loop:
data = mfc.readBlock(bIndex + block);
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;
}
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.DNO966651 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.
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).
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"
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
for "BNID", "19944342", "NO966651022 AS", "TOTAL KONTROLL AS ", "02870433", and "20210211"0x0
for "OOOOOO"0x2
for "KBDDD DDDDD"0x4
for "M"
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.
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 會返回奇怪的字符的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!