use core::fmt::Display; use crate::card::model::NfcPayload; use alloc::string::{String, ToString}; pub fn split_nfc_hex(payload: &[u8]) -> Option { if payload.len() < 0x35A { return None; } Some(NfcPayload { event_encoding: payload[0..2].try_into().ok()?, card_type: payload[2], card_uuid: payload[3..5].try_into().ok()?, _reserved: payload[5..9].try_into().ok()?, sprite: payload[9..0x2DB].try_into().ok()?, packed_card_text: payload[0x2DB..0x311].try_into().ok()?, secret: payload[0x311..0x329].try_into().ok()?, _opaque_trailer: payload[0x329..0x35A].try_into().ok()?, }) } #[derive(Debug, Clone)] pub enum Events { CCC39, CCC40, GPN24, GPN25, Unknown, } impl Display for Events { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match *self { Events::CCC39 => write!(f, "39C3"), Events::CCC40 => write!(f, "40C3"), Events::GPN24 => write!(f, "GPN24"), Events::GPN25 => write!(f, "GPN25"), Events::Unknown => write!(f, "Unknown"), } } } pub fn decode_known_event(event_encoding: &[u8]) -> Events { match event_encoding { [0x39, 0xC3] => Events::CCC39, [0x40, 0xC3] => Events::CCC40, // future proofing :) [0xE9, 0x24] => Events::GPN24, [0xE9, 0x25] => Events::GPN25, // future proofing :) _ => Events::Unknown, } } pub fn decode_secret(hex: &[u8]) -> String { let mut ascii_string = String::new(); for &byte in hex { if byte == 0 { break; } if byte.is_ascii_graphic() || byte == b' ' { ascii_string.push(byte as char); } } ascii_string } pub fn decode_packed_card_text(bytes: &[u8]) -> (String, String, String, String) { let alphabet = b" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-"; let mut full_text = String::with_capacity((bytes.len() * 8) / 6 + 1); let mut accumulator: u32 = 0; let mut bits_in_acc: u32 = 0; for &byte in bytes { accumulator |= (byte as u32) << bits_in_acc; bits_in_acc += 8; while bits_in_acc >= 6 { let char_index = (accumulator & 0x3F) as usize; full_text.push(alphabet[char_index] as char); accumulator >>= 6; bits_in_acc -= 6; } } let name = full_text[0..24].trim().to_string(); let trait1 = full_text[24..40].trim().to_string(); let trait2 = full_text[40..56].trim().to_string(); let trait3 = full_text[56..72].trim().to_string(); (name, trait1, trait2, trait3) }