Skip to content

Commit c707d06

Browse files
feat: implement hash generation
1 parent 707bbd4 commit c707d06

File tree

3 files changed

+184
-2
lines changed

3 files changed

+184
-2
lines changed

Cargo.lock

Lines changed: 131 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ repository = "https://github.com/n0-computer/dasl"
99
license = "MIT OR Apache-2.0"
1010

1111
[dependencies]
12+
blake3 = "1.8.2"
1213
data-encoding = "2.9.0"
14+
sha2 = "0.10.9"
1315
thiserror = "2.0.12"

src/cid.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use std::fmt::Display;
66
use std::str::FromStr;
77

8+
use sha2::Digest;
89
use thiserror::Error;
910

1011
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -78,14 +79,14 @@ impl FromStr for Cid {
7879
type Err = CidParseError;
7980

8081
fn from_str(s: &str) -> Result<Self, Self::Err> {
81-
if s.chars().next() != Some('b') {
82+
if !s.starts_with('b') {
8283
return Err(CidParseError::InvalidEncoding);
8384
}
8485
// TODO: verify lower case
8586

8687
// skip base encoding prefix
8788
let bytes = data_encoding::BASE32_NOPAD_NOCASE
88-
.decode(&s[1..].as_bytes())
89+
.decode(&s.as_bytes()[1..])
8990
.map_err(|_e| CidParseError::InvalidEncoding)?;
9091

9192
Cid::from_bytes(&bytes)
@@ -126,6 +127,20 @@ impl Cid {
126127

127128
out
128129
}
130+
131+
pub fn digest_sha2(codec: Codec, data: impl AsRef<[u8]>) -> Self {
132+
Self {
133+
codec,
134+
hash: Multihash::digest_sha2(data),
135+
}
136+
}
137+
138+
pub fn digest_blake3(codec: Codec, data: impl AsRef<[u8]>) -> Self {
139+
Self {
140+
codec,
141+
hash: Multihash::digest_blake3(data),
142+
}
143+
}
129144
}
130145

131146
impl Display for Cid {
@@ -197,6 +212,16 @@ impl Multihash {
197212
}
198213
out
199214
}
215+
216+
pub fn digest_sha2(data: impl AsRef<[u8]>) -> Self {
217+
let hash = sha2::Sha256::digest(data);
218+
Self::Sha2256(hash.into())
219+
}
220+
221+
pub fn digest_blake3(data: impl AsRef<[u8]>) -> Self {
222+
let hash = blake3::hash(data.as_ref());
223+
Self::Blake3(hash.into())
224+
}
200225
}
201226

202227
#[cfg(test)]
@@ -214,4 +239,28 @@ mod tests {
214239
let cid_str_back = parsed.to_string();
215240
assert_eq!(cid_str_back, cid_str);
216241
}
242+
243+
#[test]
244+
fn test_base_blake3() {
245+
// Blake3: "foo"
246+
let cid_str = "bafkr4iae4c5tt4yldi76xcpvg3etxykqkvec352im5fqbutolj2xo5yc5e";
247+
let parsed: Cid = cid_str.parse().unwrap();
248+
assert_eq!(parsed.codec(), Codec::Raw);
249+
assert!(matches!(parsed.hash(), Multihash::Blake3(_)));
250+
251+
let cid_str_back = parsed.to_string();
252+
assert_eq!(cid_str_back, cid_str);
253+
}
254+
255+
#[test]
256+
fn test_digest_sha2_256() {
257+
let cid_str = "bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy";
258+
assert_eq!(Cid::digest_sha2(Codec::Raw, b"foo").to_string(), cid_str);
259+
}
260+
261+
#[test]
262+
fn test_digest_blake3() {
263+
let cid_str = "bafkr4iae4c5tt4yldi76xcpvg3etxykqkvec352im5fqbutolj2xo5yc5e";
264+
assert_eq!(Cid::digest_blake3(Codec::Raw, b"foo").to_string(), cid_str);
265+
}
217266
}

0 commit comments

Comments
 (0)