1#![allow(dead_code)]
20
21use libnzbig::Big;
22use libnzprimes::Primes;
23
24pub struct Hash {
25 pub accumulator:Big,
26 counter:u64,
27 pub bytes:usize, }
29impl Hash {
30
31 pub fn new(size:usize) -> Hash {
32 let sizeof_accumulator = size / 4 + if size % 4 > 0 {1} else {0};
33 let mut my = Hash { accumulator:Big::new(sizeof_accumulator), counter:0, bytes:size };
34 my.accumulator.add(1);
35 return my
36 }
37
38 pub fn digest(&mut self, mut value:u32){
39 self.counter += 1;
40 value += self.counter as u32;
41 for x in 0..self.accumulator.segments.len() {
42 value += x as u32;
43 self.accumulator.shift(31);
44 self.accumulator.add( value.rotate_left(x as u32) );
45 }
46 }
47
48 pub fn get(&mut self) -> Vec<u8> {
49 let mut answer = vec![0u8;self.bytes];
50 let mut big = Big::new( self.accumulator.segments.len() );
51 big.add(1);
52 let mut primes = Primes::new();
53
54 for x in 0..self.accumulator.segments.len() {
55 for y in 0..32 {
56 let mut offset = (64 * x) + (2 * y);
57 let mask = 1u64 << y;
58 if mask & self.accumulator.segments[x] > 0 {
59 offset += 1;
60 }
61 big.multiply(primes.get(offset));
62 }
63 }
64
65 for x in 0..self.bytes {
66 answer[ x ] = ( big.segments[ x/4 ] >> (24 - ( (x % 4) * 8) )) as u8;
68 }
69
70 return answer;
71 }
72}