Skip to content

Commit

Permalink
Added base64 util to DataHash (#153)
Browse files Browse the repository at this point in the history
Adds a method to obtain the base64 of a MerkleHash to use for getting a compact representation for uses like filenames or caching paths.
  • Loading branch information
hoytak authored Jan 27, 2025
1 parent ebb9ff5 commit 53b7c3c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions merklehash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ blake3 = "1.5.1"
safe-transmute = "0.11.2"
serde = { version = "1.0.129", features = ["derive"] }
heed = "0.11"
base64 = "0.22.1"

[features]
strict = []
25 changes: 25 additions & 0 deletions merklehash/src/data_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use std::num::ParseIntError;
use std::ops::{Deref, DerefMut};
use std::{fmt, str};

// URL safe Base 64 encoding with ending characters removed.
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use base64::Engine as _;
use safe_transmute::transmute_to_bytes;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -149,6 +152,12 @@ impl DataHash {
format!("{:016x}{:016x}{:016x}{:016x}", self.0[0], self.0[1], self.0[2], self.0[3])
}

/// Gives a compact base64 representation of the hash that is more compact than hex and is
/// also url and file name safe.
pub fn base64(&self) -> String {
URL_SAFE_NO_PAD.encode(self.as_bytes())
}

/// Parses a hexadecimal string as a DataHash, returning
/// Err(DataHashHexParseError) on failure.
pub fn from_hex(h: &str) -> Result<DataHash, DataHashHexParseError> {
Expand All @@ -168,6 +177,12 @@ impl DataHash {
Ok(ret)
}

// Converts the hash from base64 (created by base64 above) to this. Used for testing.
pub fn from_base64(b64: &str) -> Result<DataHash, DataHashBytesParseError> {
let bytes = URL_SAFE_NO_PAD.decode(b64.as_bytes()).map_err(|_| DataHashBytesParseError {})?;
DataHash::from_slice(&bytes)
}

/// Returns the datahash as a raw byte slice.
pub fn as_bytes(&self) -> &[u8] {
transmute_to_bytes(&self.0[..])
Expand Down Expand Up @@ -445,4 +460,14 @@ mod tests {
// Verify that the outputs are different
assert_ne!(output1, output2,);
}

// Test the base64 usage.
#[test]
fn test_base64() {
let hash = compute_data_hash(&[0, 1, 2, 3]);

let b64 = hash.base64();

assert_eq!(hash, DataHash::from_base64(&b64).unwrap());
}
}

0 comments on commit 53b7c3c

Please sign in to comment.