当我从块到块读取Mifare经典4k卡并将字节转换为十六进制然后转换为UTF8 / ASCII时,我得到了奇怪的字符,这些字符可能控制字节而不是实际文本。 由于我只是将整个块直接转换为UTF,我应该怎么做才能利用它们之间的那些位? 以下是我得到的读数,左侧是预期的转换值。 如果您自己转换十六进制,则会发现单词之间有奇怪的字符。
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"
00000000000070f78800000000000000
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 4f 4f 20 41 53 20 00 c9 30 32 38 "ONTROOO AS" "028"
37 30 34 33 33 00 c9 32 30 32 31 30 32 31 31 00 "70433" "20210211"
00000000000070f78800000000000000
如何实现一种采用十六进制字符串或字节数组[]且仅以逗号分隔返回单词的方法?
答案 0 :(得分:2)
您可以按地址读取,可能只需要按数据地址读取。 对于Mifare Classic卡,数据地址从0到63开头,带有4个块(= 1024字节)的16个扇区。但是地址0始终存储UID或制造商ID。因此,从地址1,地址2 ...地址63开始阅读。让我为您分解,
Sector 0: Address 0 , Address 1, Address 2, Address 3
UID/ManufacturerID, Data , Data ,Sector Trail (KeyA,AccessKey,KeyB)
Sector 1: Address 4, Address 5, Address 6, Address 7
Data , Data , Data , Sector Trail
...
Sector 63 ...
So Sector Trail = 00000000000070f78800000000000000
KeyA = 000000000000
AccessKey = 70f78800
KeyB = 000000000000
因此,如果未设置读写保护,则每个扇区都将跳过最后一个地址。因此,请尝试此操作。并相应地进行更改,这足以读取
// final data
String data="";
// read sector 1 and 2
for(int sector = 1; sector < 3, sector++){
// auth sector
auth = mfc.authenticateSectorWithKeyA(sector, bytekey3);
if(auth) {
// read blocks from sector
data += convertHexToString(readBlockData(sector)).trim();
}
}
// read block
private String readBlockData(int sector) {
String blockvalues = "";
// Read all blocks in sector
for (int block = 0; (block < mfc.getBlockCountInSector(sector)); ++block) {
// Get block number for sector + block
int blockIndex = (mfc.sectorToBlock(sector) + block);
try {
// Create a string of bits from block data and fix endianness
// http://en.wikipedia.org/wiki/Endianness
if (block < 3) {
// Read block data from block index
byte[] data = mfc.readBlock(blockIndex);
if (!(sector == 0 && block == 0)) {
String temp = ByteArrayToHexString(data);
blockvalues += temp;
Log.i(TAG, "Block " + blockIndex + " : " + temp);
rawData += ("Block " + blockIndex + " : " + temp + "\n");
}
}
} catch (IOException e) {
Log.e(TAG, "Exception occurred " + e.getLocalizedMessage());
}
}
return blockvalues.trim();
}
public String convertHexToString(String hex) {
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
//49204c6f7665204a617661 split into two characters 49, 20, 4c...
for (int i = 0; i < hex.length() - 1; i += 2) {
//grab the hex in pairs
String output = hex.substring(i, (i + 2));
//convert hex to decimal
int decimal = Integer.parseInt(output, 16);
//convert the decimal to character
sb.append((char) decimal);
temp.append(decimal);
}
System.out.println("Decimal : " + temp.toString());
return sb.toString().trim();
}
private String ByteArrayToHexString(byte[] inarray) {
int i, j, in;
String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A",
"B", "C", "D", "E", "F"};
String out = "";
for (j = 0; j < inarray.length; ++j) {
in = inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
}
return out;
}
最后一部分将是字符串操作。因此,基本上,请使用空格重播所有双引号,并使用String [] yourdata = data.split(“ \ s +”);您将获得数据。我从此link
借用的一些代码