b64
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -299,6 +299,17 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.11.0"
|
||||
@@ -340,6 +351,7 @@ dependencies = [
|
||||
"clap",
|
||||
"hex",
|
||||
"lofty",
|
||||
"sha1",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
|
||||
@@ -10,4 +10,5 @@ authors = ["Owen Feldman"]
|
||||
clap = { version = "4.6.6", features = ["derive"] }
|
||||
hex = "0.4.3"
|
||||
lofty = "0.25.1"
|
||||
sha1 = "0.11.0"
|
||||
sha2 = "0.11.0"
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
mod disc_id;
|
||||
|
||||
use clap::{
|
||||
Parser, Subcommand,
|
||||
builder::styling::{AnsiColor, Effects, Styles},
|
||||
|
||||
Reference in New Issue
Block a user