use crate::Platform;
use wasm_bindgen::prelude::*;
const CRC_INIT_VALUE: u32 = 0xFFFFFFFF;
const CRC_XOROUT: u32 = 0xAAAA;
const fn build_crc_algorithm(polynomial: u32) -> crc::Algorithm<u32> {
crc::Algorithm::<u32> {
width: 32,
poly: polynomial,
init: CRC_INIT_VALUE,
refin: true,
refout: true,
xorout: CRC_XOROUT,
check: 0,
residue: 0,
}
}
const CRC_POLYNOMIAL_WII_AND_DSI: u32 = 0x04C11DB7;
const CRC_POLYNOMIAL_WIIU_AND_3DS: u32 = 0x04C65DB7;
const CRC_ALGORITHM_WII_AND_DSI: crc::Algorithm<u32> =
build_crc_algorithm(CRC_POLYNOMIAL_WII_AND_DSI);
const CRC_ALGORITHM_WIIU_AND_3DS: crc::Algorithm<u32> =
build_crc_algorithm(CRC_POLYNOMIAL_WIIU_AND_3DS);
const CRC_ADDOUT_WII_AND_DSI: u32 = 0x14C1;
const CRC_ADDOUT_WIIU_AND_3DS: u32 = 0x1657;
const fn get_crc(platform: Platform) -> (&'static crc::Algorithm<u32>, u32) {
match platform {
Platform::Wii | Platform::Dsi => (&CRC_ALGORITHM_WII_AND_DSI, CRC_ADDOUT_WII_AND_DSI),
Platform::WiiU | Platform::The3ds => (&CRC_ALGORITHM_WIIU_AND_3DS, CRC_ADDOUT_WIIU_AND_3DS),
Platform::Switch => panic!(
"The version 0 of the parental control master key algorithm is not available on the Nintendo Switch Platform"
),
}
}
#[wasm_bindgen]
pub fn calculate_v0_master_key(platform: Platform, inquiry_number: u32, day: u8, month: u8) -> u32 {
assert!(inquiry_number <= 99_999_999);
assert!(day > 0);
assert!(day <= 31);
assert!(month > 0);
assert!(month <= 12);
let (algorithm, addout) = get_crc(platform);
let input = format!("{month:0>2}{day:0>2}{:0>4}", inquiry_number % 10000);
let crc = crc::Crc::<u32>::new(algorithm);
let checksum = (crc.checksum(input.as_bytes())) + addout;
checksum % 100000
}
#[cfg(test)]
mod tests {
use super::*;
const INQUIRY_NUMBER: u32 = 84293062;
const DAY: u8 = 5;
const MONTH: u8 = 8;
#[test]
fn wii_platform() {
assert_eq!(
calculate_v0_master_key(Platform::Wii, INQUIRY_NUMBER, DAY, MONTH),
66150
);
}
#[test]
fn dsi_platform() {
assert_eq!(
calculate_v0_master_key(Platform::Dsi, INQUIRY_NUMBER, DAY, MONTH),
66150
);
}
#[test]
fn wiiu_platform() {
assert_eq!(
calculate_v0_master_key(Platform::WiiU, INQUIRY_NUMBER, DAY, MONTH),
87902
);
}
#[test]
fn the_3ds_platform() {
assert_eq!(
calculate_v0_master_key(Platform::The3ds, INQUIRY_NUMBER, DAY, MONTH),
87902
);
}
}