How to Parse received Hex bytes into readable string

274 Views Asked by At

As the title says, I've been working on MiFare Classic reading a card. I'm using the MiFare v1.1.3 Library from NuGet

and it returns a byte array, which I parse to readable Hex strings, by looping thru it.

Here's the code snippet:

int sector = 1;
int block = 0;
int size = 16;
var data = await localCard.GetData(sector, block, size);
string hexString = "";
for (int i = 0; i < data.Length; i++)
{
    hexString += data[i].ToString("X2") + " ";
}
// hexString returns 84 3D 17 B0 1E 08 04 00 02 63 B5 F6 B9 BE 77 1D

Now, how can I parse it properly?

I've tried parsing it into ASCII, ANSI, Int, Int64, Base64, Long and all of them didn't match the 'data' that it's suppose to contain

EDIT: The expected output: 1206058 HEX String returned: 84 3D 17 B0 1E 08 04 00 02 63 B5 F6 B9 BE 77 1D

3

There are 3 best solutions below

2
Auditive On

If var data potentially is string - you can reverse it from hex by:

// To Hex
byte[] plainBytes = Encoding.ASCII.GetBytes("MiFare v1.1.3");
string hexString = "";

for (int i = 0; i < plainBytes.Length; i++)
    hexString += plainBytes[i].ToString("X2") + " ";

Console.WriteLine(hexString); // Result: "4D 69 46 61 72 65 20 76 31 2E 31 2E 33"
        
// From Hex
hexString = hexString.Replace(" ", ""); // Remove whitespaces to have "4D69466172652076312E312E33"  
byte[] hexBytes = new byte[hexString.Length / 2];

for (int i = 0; i < hexString.Length / 2; i++)
    hexBytes[i] = Convert.ToByte(hexString.Substring(2 * i, 2), 16);

string plainString = Encoding.ASCII.GetString(hexBytes);    
Console.WriteLine(plainString); // Result: "MiFare v1.1.3"

Just, probably, should be needed to define correct Encoding.

1
Kapitany On

I have written a simple program to solve your problem. Perhaps this is what you want to achieve:

// The original byte data array; some random data
byte[] data = { 0, 1, 2, 3, 4, 85, 128, 255 };

// Byte data -> Hex string
StringBuilder hexString = new StringBuilder();

foreach (byte item in data)
{
    hexString.Append($"{item.ToString("X2")} ");
}

Console.WriteLine(hexString.ToString().Trim());

// Hex string -> List of bytes
string[] hexArray = hexString.ToString().Trim().Split(' ');
List<byte> dataList = new List<byte>();

foreach (string item in hexArray)
{
    dataList.Add(byte.Parse(item, System.Globalization.NumberStyles.HexNumber));
}

dataList.ForEach(b => Console.Write($"{b} "));
Console.WriteLine();

If it is not the right solution please provide us more info about your problem.

2
oleksa On

I've checked the source code

it looks like both Task<byte[]> GetData Task SetData methods do not have any special logic to transform the data. Data are just saved (and read) as byte[]

I suppose that you have to contact author/company that has wrote data you are trying to read.

The expected output: 1206058

Looks strange since you are reading 16 bytes size = 16 and expecting 7 characters to be read.

Is it possible that block or sector values are incorrect ?