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:
Alienscience 2022-01-30 10:52:14 +01:00
parent cc92539899
commit c9d3084622
3 changed files with 30 additions and 20 deletions

View file

@ -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]);
}

View file

@ -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])
});

View file

@ -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]);
}