From e2f9bdd52ec5842dc3b745e2b483fd3d0bcc9e86 Mon Sep 17 00:00:00 2001 From: Russell Banks <74878137+russellbanks@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:50:45 +0000 Subject: [PATCH] Use fast32 to encode hash with Crockford Base32 --- Cargo.toml | 3 ++- README.md | 6 +++--- src/lib.rs | 33 +++++++++++---------------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7be2763..e790886 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "package-family-name" -version = "1.0.0" +version = "1.1.0" edition = "2021" license = "MIT OR Apache-2.0" categories = ["no-std"] @@ -10,4 +10,5 @@ readme = "README.md" repository = "https://github.com/russellbanks/package-family-name" [dependencies] +fast32 = "1" sha2 = { version = "0.10", default-features = false } diff --git a/README.md b/README.md index 4bd7987..6d54a4f 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,9 @@ In short, a package family name is made up of two parts: These steps are then taken: -1. Calculate the SHA256 hash of the identity publisher -2. Take the first 8 bytes of the hash -3. Left shift all bits +1. UTF-16 encode the identity publisher +2. Calculate a SHA256 hash of the encoded publisher +3. Take the first 8 bytes of the hash 4. Encode the result with [Douglas Crockford Base32](http://www.crockford.com/base32.html) 5. Join the identity name and the encoded value with an underscore (`AppName_zj75k085cmj1a`) diff --git a/src/lib.rs b/src/lib.rs index 54553ee..728915a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,40 +4,29 @@ extern crate alloc; use alloc::format; use alloc::string::String; -use alloc::vec::Vec; -use core::fmt::Write; -use core::ops::Add; +use fast32::base32::Alphabet32Nopad; +use fast32::decoder_map_simple; use sha2::{Digest, Sha256}; const CROCKFORD_CHARACTER_TABLE: &[u8; 32] = b"0123456789abcdefghjkmnpqrstvwxyz"; +const ENC_CROCKFORD_LOWER: [u8; 256] = decoder_map_simple(CROCKFORD_CHARACTER_TABLE); +const CROCKFORD_LOWER: Alphabet32Nopad = + Alphabet32Nopad::new(CROCKFORD_CHARACTER_TABLE, &ENC_CROCKFORD_LOWER); pub fn get_package_family_name(identity_name: &str, identity_publisher: &str) -> String { - let result: String = identity_publisher + let publisher_sha_256 = identity_publisher .encode_utf16() .flat_map(u16::to_le_bytes) .fold(Sha256::new(), |mut buf, byte| { buf.update([byte]); buf }) - .finalize() - .into_iter() - .take(8) - .fold(String::with_capacity(65), |mut buf, byte| { - let _ = write!(buf, "{:08b}", byte); - buf - }) - .add("0") - .chars() - .collect::>() - .chunks_exact(5) - .map(|chunk| { - let chunk_str = String::from_iter(chunk); - let index = usize::from_str_radix(&chunk_str, 2).unwrap_or_default(); - CROCKFORD_CHARACTER_TABLE[index] as char - }) - .collect(); + .finalize(); - format!("{identity_name}_{}", result) + format!( + "{identity_name}_{}", + CROCKFORD_LOWER.encode(&publisher_sha_256[..8]) + ) } #[cfg(test)]