Files
creaturedex/src/card/decoder.rs
T

96 lines
2.6 KiB
Rust

use core::fmt::Display;
use crate::card::model::NfcPayload;
use alloc::string::{String, ToString};
pub fn split_nfc_hex(payload: &[u8]) -> Option<NfcPayload> {
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)
}