1use hash_db::Hasher;
18use keccak_hasher::KeccakHasher;
19
20type H256 = <KeccakHasher as hash_db::Hasher>::Out;
21
22pub enum Alphabet {
24 All,
26 Low,
28 Mid,
30 Custom(Vec<u8>),
32}
33
34pub enum ValueMode {
36 Mirror,
38 Random,
40 Index,
42}
43
44pub struct StandardMap {
46 pub alphabet: Alphabet,
48 pub min_key: usize,
50 pub journal_key: usize,
52 pub value_mode: ValueMode,
54 pub count: u32,
56}
57
58impl StandardMap {
59 fn random_bytes(min_count: usize, journal_count: usize, seed: &mut H256) -> Vec<u8> {
62 assert!(min_count + journal_count <= 32);
63 *seed = KeccakHasher::hash(&seed[..]);
64 let r = min_count + (seed[31] as usize % (journal_count + 1));
65 seed[0..r].to_vec()
66 }
67
68 fn random_value(seed: &mut H256) -> Vec<u8> {
71 *seed = KeccakHasher::hash(&seed[..]);
72 match seed[0] % 2 {
73 1 => vec![seed[31]; 1],
74 _ => seed.to_vec(),
75 }
76 }
77
78 fn random_word(
81 alphabet: &[u8],
82 min_count: usize,
83 journal_count: usize,
84 seed: &mut H256,
85 ) -> Vec<u8> {
86 assert!(min_count + journal_count <= 32);
87 *seed = KeccakHasher::hash(&seed[..]);
88 let r = min_count + (seed[31] as usize % (journal_count + 1));
89 let mut ret: Vec<u8> = Vec::with_capacity(r);
90 for i in 0..r {
91 ret.push(alphabet[seed[i] as usize % alphabet.len()]);
92 }
93 ret
94 }
95
96 pub fn make(&self) -> Vec<(Vec<u8>, Vec<u8>)> {
98 self.make_with(&mut H256::default())
99 }
100
101 pub fn make_with(&self, seed: &mut H256) -> Vec<(Vec<u8>, Vec<u8>)> {
104 let low = b"abcdef";
105 let mid = b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
106
107 let mut d: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
108 for index in 0..self.count {
109 let k = match self.alphabet {
110 Alphabet::All => Self::random_bytes(self.min_key, self.journal_key, seed),
111 Alphabet::Low => Self::random_word(low, self.min_key, self.journal_key, seed),
112 Alphabet::Mid => Self::random_word(mid, self.min_key, self.journal_key, seed),
113 Alphabet::Custom(ref a) =>
114 Self::random_word(a, self.min_key, self.journal_key, seed),
115 };
116 let v = match self.value_mode {
117 ValueMode::Mirror => k.clone(),
118 ValueMode::Random => Self::random_value(seed),
119 ValueMode::Index =>
120 vec![index as u8, (index >> 8) as u8, (index >> 16) as u8, (index >> 24) as u8],
121 };
122 d.push((k, v))
123 }
124 d
125 }
126}