Made api clearer.
- Update rather than calculate. - Update does not reset the current hash value. The documentation before was wrong. - Standalone calculate for when rolling is not needed.
This commit is contained in:
parent
cc92539899
commit
c9d3084622
|
@ -11,11 +11,11 @@ fn random_vector(length: usize) -> Vec<u8> {
|
|||
}
|
||||
|
||||
fn cyclic_poly32_block(block: &[u8]) -> u32 {
|
||||
CyclicPoly32::from_block(block).value()
|
||||
CyclicPoly32::calculate(block)
|
||||
}
|
||||
|
||||
fn cyclic_poly64_block(block: &[u8]) -> u64 {
|
||||
CyclicPoly64::from_block(block).value()
|
||||
CyclicPoly64::calculate(block)
|
||||
}
|
||||
|
||||
fn adler32_block(block: &[u8]) -> u32 {
|
||||
|
@ -51,8 +51,7 @@ fn single_block(cap: usize) {
|
|||
}
|
||||
|
||||
fn cyclic_poly32_rolling(v: &[u8], blocksize: usize) -> u32 {
|
||||
let mut cpoly = CyclicPoly32::new(blocksize);
|
||||
cpoly.calculate(&v[0..blocksize]);
|
||||
let mut cpoly = CyclicPoly32::from_block(&v[0..blocksize]);
|
||||
for i in blocksize..v.len() {
|
||||
cpoly.rotate(v[i - blocksize], v[i]);
|
||||
}
|
||||
|
@ -60,8 +59,7 @@ fn cyclic_poly32_rolling(v: &[u8], blocksize: usize) -> u32 {
|
|||
}
|
||||
|
||||
fn cyclic_poly64_rolling(v: &[u8], blocksize: usize) -> u64 {
|
||||
let mut cpoly = CyclicPoly64::new(blocksize);
|
||||
cpoly.calculate(&v[0..blocksize]);
|
||||
let mut cpoly = CyclicPoly64::from_block(&v[0..blocksize]);
|
||||
for i in blocksize..v.len() {
|
||||
cpoly.rotate(v[i - blocksize], v[i]);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ fn collisions() {
|
|||
});
|
||||
|
||||
// Cyclic Poly
|
||||
let mut cyclic_poly = CyclicPoly32::new(block_size);
|
||||
let first = cyclic_poly.calculate(&data[0..block_size]);
|
||||
let mut cyclic_poly = CyclicPoly32::from_block(&data[0..block_size]);
|
||||
let first = cyclic_poly.value();
|
||||
count_collisions("cyclic_poly 32", Some(first), num_hashes - 1, |i| {
|
||||
cyclic_poly.rotate(data[i], data[i + block_size])
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@ impl<T: HashValue> CyclicPoly<T> {
|
|||
///
|
||||
/// let data = vec![0, 1, 2, 3];
|
||||
/// let mut hasher = CyclicPoly32::new(4);
|
||||
/// let hash_value = hasher.calculate(&data);
|
||||
/// let hash_value = hasher.update(&data);
|
||||
/// assert_eq!(hash_value, 0xecf6e475);
|
||||
/// ```
|
||||
pub fn new(block_size: usize) -> Self {
|
||||
|
@ -45,7 +45,7 @@ impl<T: HashValue> CyclicPoly<T> {
|
|||
/// ```
|
||||
pub fn from_block(block: &[u8]) -> Self {
|
||||
let mut ret = Self::new(block.len());
|
||||
ret.calculate(block);
|
||||
ret.update(block);
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ impl<T: HashValue> CyclicPoly<T> {
|
|||
///
|
||||
/// let data = vec![8, 0, 1, 2, 3];
|
||||
/// let mut hasher = CyclicPoly32::new(4);
|
||||
/// hasher.calculate(&data[0..4]);
|
||||
/// hasher.update(&data[0..4]);
|
||||
/// let hash_value = hasher.rotate(data[0], data[4]);
|
||||
/// assert_eq!(hash_value, 0xecf6e475);
|
||||
/// ```
|
||||
|
@ -76,17 +76,29 @@ impl<T: HashValue> CyclicPoly<T> {
|
|||
self.current
|
||||
}
|
||||
|
||||
/// Reset the hash function and calculate the hash value of the given block.
|
||||
pub fn calculate(&mut self, block: &[u8]) -> T {
|
||||
for v in block.iter() {
|
||||
let current = self.current.rotate_left(1);
|
||||
let b = usize::from(*v);
|
||||
let t = T::TRANSFORMATION[b];
|
||||
self.current = current ^ t;
|
||||
}
|
||||
/// Update the current hash value from the given block.
|
||||
/// Returns the updated hash value.
|
||||
pub fn update(&mut self, block: &[u8]) -> T {
|
||||
self.current = Self::stateless_update(self.current, block);
|
||||
self.current
|
||||
}
|
||||
|
||||
/// Calculate a single hash value from the given block.
|
||||
/// This function does not support rolling hashes but saves the initial
|
||||
/// setup that is done when calling new().
|
||||
pub fn calculate(block: &[u8]) -> T {
|
||||
Self::stateless_update(T::zero(), block)
|
||||
}
|
||||
|
||||
// Calculate a new hash value from the given current value and a new block of data.
|
||||
fn stateless_update(current: T, block: &[u8]) -> T {
|
||||
block
|
||||
.iter()
|
||||
.map(|b| usize::from(*b))
|
||||
.map(|b| T::TRANSFORMATION[b])
|
||||
.fold(current, |acc, t| acc.rotate_left(1) ^ t)
|
||||
}
|
||||
|
||||
/// Given the hash value of a parent, and the second child block, calculate the hash
|
||||
/// value of the first child.
|
||||
///
|
||||
|
@ -193,7 +205,7 @@ mod tests {
|
|||
let last_block = &data[(data_len - n)..data_len];
|
||||
let full: T = CyclicPoly::from_block(last_block).value();
|
||||
let mut rolling: CyclicPoly<T> = CyclicPoly::new(n);
|
||||
rolling.calculate(&data[0..n]);
|
||||
rolling.update(&data[0..n]);
|
||||
for i in n..data_len {
|
||||
rolling.rotate(data[i - n], data[i]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue