/// <summary> /// /// </summary> /// <param name="st"></param> /// <param name="_sector"></param> /// <returns></returns> private bool decodeSectorTrailer(string st, MifareClassicSectorModel _sector) { byte[] _bytes = new byte[255]; int discarded = 0; string[] sectorTrailer = st.Split(new[] { ',', ';' }); if (sectorTrailer.Count() != 3 || !(CustomConverter.IsInHexFormat(sectorTrailer[1]) && sectorTrailer[1].Length == 8) || !(CustomConverter.IsInHexFormat(sectorTrailer[0]) && sectorTrailer[0].Length == 12) || !(CustomConverter.IsInHexFormat(sectorTrailer[2]) && sectorTrailer[2].Length == 12)) { return(true); } _bytes = CustomConverter.GetBytes(sectorTrailer[1], out discarded); if (!decodeSectorTrailer(_bytes, ref _sector)) { return(false); } else { return(true); } }
/// <summary> /// Converts a given selection for either sector /// access bits or datablock access bits to the equivalent 3 bytes sector trailer /// </summary> /// <param name="_sector"></param> /// <returns></returns> private string encodeSectorTrailer(MifareClassicSectorModel _sector) { byte[] st = new byte[4] { 0x00, 0x00, 0x00, 0xC3 }; uint sectorAccessBitsIndex = (uint)_sector.Cx; //_sector.Sector_AccessCondition.Cx; uint dataBlock0AccessBitsIndex = (uint)_sector.DataBlock0.Cx; //(uint)dataBlock_AccessBits.IndexOf(_sector); //_sector.DataBlock0_AccessCondition.Cx; uint dataBlock1AccessBitsIndex = (uint)_sector.DataBlock1.Cx; //_sector.DataBlock1_AccessCondition.Cx; uint dataBlock2AccessBitsIndex = (uint)_sector.DataBlock2.Cx; //_sector.DataBlock2_AccessCondition.Cx; // DataBlock 0 = C1/0; C2/0; C3/0 st[1] |= (byte)((dataBlock0AccessBitsIndex & 0x01) << 4); // C1/0 st[2] |= (byte)((dataBlock0AccessBitsIndex & 0x02) >> 1); // C2/0 st[2] |= (byte)((dataBlock0AccessBitsIndex & 0x04) << 2); // C3/0 // DataBlock 1 = C1/1; C2/1; C3/1 st[1] |= (byte)((dataBlock1AccessBitsIndex & 0x01) << 5); // C1/1 st[2] |= (byte)(dataBlock1AccessBitsIndex & 0x02); // C2/1 st[2] |= (byte)((dataBlock1AccessBitsIndex & 0x04) << 3); // C3/1 // DataBlock 2 = C1/2; C2/2; C3/2 st[1] |= (byte)((dataBlock2AccessBitsIndex & 0x01) << 6); // C1/2 st[2] |= (byte)((dataBlock2AccessBitsIndex & 0x02) << 1); // C2/2 st[2] |= (byte)((dataBlock2AccessBitsIndex & 0x04) << 4); // C3/2 // SectorAccessBits = C1/3; C2/3; C3/3 st[1] |= (byte)((sectorAccessBitsIndex & 0x01) << 7); // C1/3 st[2] |= (byte)((sectorAccessBitsIndex & 0x02) << 2); // C2/3 st[2] |= (byte)((sectorAccessBitsIndex & 0x04) << 5); // C3/3 st = CustomConverter.buildSectorTrailerInvNibble(st); string[] stAsString; // if (!string.IsNullOrWhiteSpace(_sector.AccessBitsAsString)) // stAsString = _sector.AccessBitsAsString.Split(new[] { ',', ';' }); // else stAsString = new string[] { "FFFFFFFFFFFF", "FF0780C3", "FFFFFFFFFFFF" }; stAsString[1] = CustomConverter.HexToString(st); return(string.Join(",", stAsString)); }
/// <summary> /// turns a given byte or string sector trailer to a access bits selection /// </summary> /// <param name="st"></param> /// <param name="_sector"></param> /// <returns></returns> private bool decodeSectorTrailer(byte[] st, ref MifareClassicSectorModel _sector) { uint C1x, C2x; LibLogicalAccess.SectorAccessBits sab; uint tmpAccessBitCx; if (CustomConverter.SectorTrailerHasWrongFormat(st)) { _sector = null; return(true); } #region getAccessBitsForSectorTrailer C1x = st[1]; C2x = st[2]; C1x &= 0xF0; C1x >>= 7; C1x &= 0x01; sab.d_sector_trailer_access_bits.c1 = (short)C1x; C2x >>= 2; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 1; tmpAccessBitCx &= 0x01; sab.d_sector_trailer_access_bits.c2 = (short)tmpAccessBitCx; C1x |= C2x; C2x >>= 3; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 2; tmpAccessBitCx &= 0x01; sab.d_sector_trailer_access_bits.c3 = (short)tmpAccessBitCx; C1x &= 0x03; C1x |= C2x; C1x &= 0x07; //now we have C1³ + C2³ + C3³ as integer in C1x see mifare manual // // if (C1x == 4) // isTransportConfiguration = true; // else // isTransportConfiguration = false; _sector.SectorAccessCondition = sectorTrailer_AccessBits[(int)C1x]; #endregion getAccessBitsForSectorTrailer #region getAccessBitsForDataBlock2 C1x = st[1]; C2x = st[2]; C1x &= 0xF0; C1x >>= 6; C1x &= 0x01; sab.d_data_block2_access_bits.c1 = (short)C1x; C2x >>= 1; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 1; tmpAccessBitCx &= 0x01; sab.d_data_block2_access_bits.c2 = (short)tmpAccessBitCx; C1x |= C2x; //C2 &= 0xF8; C2x >>= 3; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 2; tmpAccessBitCx &= 0x01; sab.d_data_block2_access_bits.c3 = (short)tmpAccessBitCx; C1x &= 0x03; C1x |= C2x; C1x &= 0x07; //if(isTransportConfiguration) // decodedBlock2AccessBits = dataBlockABs[C1x]; //else // decodedBlock2AccessBits = dataBlockAB[C1x]; DataBlock2.DataBlockAccessCondition = dataBlock_AccessBits[(int)C1x]; //dataBlock2_AccessCondition = new DataBlock_AccessCondition(2, sab.d_data_block2_access_bits.c1, sab.d_data_block2_access_bits.c2, sab.d_data_block2_access_bits.c3); #endregion getAccessBitsForDataBlock2 #region getAccessBitsForDataBlock1 C1x = st[1]; C2x = st[2]; C1x &= 0xF0; C1x >>= 5; C1x &= 0x01; sab.d_data_block1_access_bits.c1 = (short)C1x; C1x |= C2x; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 1; tmpAccessBitCx &= 0x01; sab.d_data_block1_access_bits.c2 = (short)tmpAccessBitCx; C2x >>= 3; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 2; tmpAccessBitCx &= 0x01; sab.d_data_block1_access_bits.c3 = (short)tmpAccessBitCx; C1x &= 0x03; C1x |= C2x; C1x &= 0x07; //if(isTransportConfiguration) // decodedBlock1AccessBits = dataBlockABs[C1x]; //else // decodedBlock1AccessBits = dataBlockAB[C1x]; DataBlock1.DataBlockAccessCondition = dataBlock_AccessBits[(int)C1x]; #endregion getAccessBitsForDataBlock1 #region getAccessBitsForDataBlock0 C1x = st[1]; C2x = st[2]; C1x &= 0xF0; C1x >>= 4; C1x &= 0x01; tmpAccessBitCx = C1x; tmpAccessBitCx &= 0x01; sab.d_data_block0_access_bits.c1 = (short)C1x; tmpAccessBitCx = C2x; tmpAccessBitCx &= 0x01; sab.d_data_block0_access_bits.c2 = (short)C1x; C2x <<= 1; C1x |= C2x; C2x >>= 3; tmpAccessBitCx = C2x; tmpAccessBitCx >>= 2; tmpAccessBitCx &= 0x01; sab.d_data_block0_access_bits.c3 = (short)C1x; C2x &= 0xFC; C1x &= 0x03; C1x |= C2x; C1x &= 0x07; DataBlock0.DataBlockAccessCondition = dataBlock_AccessBits[(int)C1x]; if (DataBlock0.DataBlockAccessCondition == DataBlock1.DataBlockAccessCondition && DataBlock1.DataBlockAccessCondition == DataBlock2.DataBlockAccessCondition) { DataBlockCombined.DataBlockAccessCondition = DataBlock0.DataBlockAccessCondition; } #endregion getAccessBitsForDataBlock0 return(false); }