b64
This commit is contained in:
69
src/disc_id.rs
Normal file
69
src/disc_id.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use std::{convert, ops::Index};
|
||||
|
||||
const B64TABLE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
|
||||
|
||||
fn b64(data: &[u8]) -> String {
|
||||
let binary: Vec<u8> = data
|
||||
.iter()
|
||||
.flat_map(|b| (0..8).rev().map(move |i| (b >> i) & 1))
|
||||
.collect();
|
||||
let mut chunks: Vec<Vec<u8>> = binary.chunks(6).map(|s| s.to_vec()).collect();
|
||||
let last = chunks.last_mut().unwrap();
|
||||
if last.len() < 6 {
|
||||
for _ in last.len()..6 {
|
||||
last.push(0);
|
||||
}
|
||||
}
|
||||
let decimal: Vec<u8> = chunks
|
||||
.iter()
|
||||
.map(|bits| bits.iter().fold(0, |acc, &bit| (acc << 1) | bit))
|
||||
.collect();
|
||||
let mut converted: Vec<String> = Vec::new();
|
||||
|
||||
for dec in decimal {
|
||||
converted.push(B64TABLE.chars().nth(dec as usize).unwrap().to_string());
|
||||
}
|
||||
match data.len() % 3 {
|
||||
1 => {
|
||||
converted.push("--".to_string());
|
||||
}
|
||||
2 => {
|
||||
converted.push("-".to_string());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
converted.join("")
|
||||
}
|
||||
pub fn compute_disc_id(first_track: u8, last_track: u8, leadout: u32, offsets: &[u32]) -> String {
|
||||
let mut toc = String::new();
|
||||
toc.push_str(&format!("{first_track:02X}{last_track:02X}{leadout:08X}"));
|
||||
for i in 0..99 {
|
||||
let offset = offsets.get(i).copied().unwrap_or(0);
|
||||
toc.push_str(&format!("{:08X}", offset));
|
||||
}
|
||||
toc
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn known_example() {
|
||||
let first_track = 1;
|
||||
let last_track = 12;
|
||||
let leadout = 224556;
|
||||
let offsets = [
|
||||
150, 9078, 13528, 34182, 53768, 70987, 96424, 118425, 136793, 159514, 179777, 198006,
|
||||
];
|
||||
assert_eq!(
|
||||
compute_disc_id(first_track, last_track, leadout, &offsets),
|
||||
"T_prJXQSrqbnH8OE.dgOKsHm5Uw-"
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn base64() {
|
||||
assert_eq!(b64("Man".as_bytes()), "TWFu".to_string());
|
||||
assert_eq!(b64("M".as_bytes()), "TQ--".to_string());
|
||||
assert_eq!(b64("Ma".as_bytes()), "TWE-".to_string());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user