Skip to content

Commit aff3b7f

Browse files
authored
feat: Hash and Multihash arbitrary (#51)
Both for internal purposes and for use by other crates
1 parent 2a6373e commit aff3b7f

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ sha-1 = { version = "0.8", default-features = false }
1818
sha2 = { version = "0.8", default-features = false }
1919
sha3 = { version = "0.8", default-features = false }
2020
unsigned-varint = "0.3"
21+
quickcheck = { version = "0.9.2", optional = true }
22+
rand = { version = "0.7.3", optional = true }
2123

2224
[dev-dependencies]
2325
criterion = "0.3"
24-
rand = "0.7"
2526
quickcheck = "0.9.2"
27+
rand = "0.7.3"
28+
29+
[features]
30+
test = ["quickcheck", "rand"]
2631

2732
[[bench]]
2833
name = "multihash"

src/arb.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use crate::{Code, Code::*, Multihash};
2+
use quickcheck::{Arbitrary, Gen};
3+
use rand::seq::SliceRandom;
4+
5+
const HASHES: [Code; 16] = [
6+
Identity, Sha1, Sha2_256, Sha2_512, Sha3_512, Sha3_384, Sha3_256, Sha3_224, Keccak224,
7+
Keccak256, Keccak384, Keccak512, Blake2b256, Blake2b512, Blake2s128, Blake2s256,
8+
];
9+
10+
/// Generates a random hash algorithm.
11+
///
12+
/// The more exotic ones will be generated just as frequently as the common ones.
13+
impl Arbitrary for Code {
14+
fn arbitrary<G: Gen>(g: &mut G) -> Self {
15+
*HASHES.choose(g).unwrap()
16+
}
17+
}
18+
19+
/// Generates a random valid multihash.
20+
///
21+
/// This is done by encoding a random piece of data.
22+
impl Arbitrary for Multihash {
23+
fn arbitrary<G: Gen>(g: &mut G) -> Self {
24+
let code: Code = Arbitrary::arbitrary(g);
25+
let data: Vec<u8> = Arbitrary::arbitrary(g);
26+
// encoding an actual random piece of data might be better than just choosing
27+
// random numbers of the appropriate size, since some hash algos might produce
28+
// a limited set of values
29+
code.hasher().unwrap().digest(&data)
30+
}
31+
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ mod errors;
1313
mod hashes;
1414
mod storage;
1515

16+
#[cfg(any(test, feature = "test"))]
17+
mod arb;
18+
1619
pub use digests::{wrap, Multihash, MultihashDigest, MultihashRef};
1720
pub use errors::{DecodeError, DecodeOwnedError, EncodeError};
1821
pub use hashes::*;

0 commit comments

Comments
 (0)