/* * hashtree.cpp * serp++ * * Created by Victor Grishchenko on 3/6/09. * Copyright 2009 Delft Technical University. All rights reserved. * */ #include "hashtree.h" #include #include #include #include #include #include using namespace std; #define HASHSZ 20 const size_t Sha1Hash::SIZE = HASHSZ; const Sha1Hash Sha1Hash::ZERO = Sha1Hash(); Sha1Hash::Sha1Hash(const Sha1Hash& left, const Sha1Hash& right) { uint8_t data[HASHSZ*2]; memcpy(data,left.bits,SIZE); memcpy(data+SIZE,right.bits,SIZE); SHA1(data,SIZE*2,bits); } Sha1Hash::Sha1Hash(const uint8_t* data, size_t length) { SHA1(data,length,bits); } Sha1Hash::Sha1Hash(const char* str) { SHA1((const unsigned char*)str,strlen(str),bits); } Sha1Hash::Sha1Hash(bool hex, const char* hash) { assert(!hex); memcpy(bits,hash,SIZE); } string Sha1Hash::hex() { char hex[HASHSZ*2+1]; for(int i=0; i>10) + (st.st_size%1024 ? 1 : 0); mass = bin::lenpeak(length); // incorrect bits.resize(mass+1); status.resize(mass+1); uint8_t buf[1024]; for(bin i=1; i<=mass; i++) if (i.layer()) { bits[i] = Sha1Hash(bits[i.left()],bits[i.right()]); } else { int len = pread(fd,buf,1024,i.offset()<<10); bits[i] = Sha1Hash(buf,len); } //close(fd); bin::vec p = bin::peaks(length); while(p.size()) { peaks.push_back(binhash(p.front(),bits[p.front()])); p.pop_front(); } root = deriveRoot(); } HashTree::HashTree (const Sha1Hash& with_root) : root(with_root), length(0), mass(0) { // recover the partially filled hash file // first, size // then, peaks // works? then offer the rest } HashTree::~HashTree () { close(fd); } HashTree::hashres_t HashTree::offerPeak (bin pos, Sha1Hash hash) { if (bin(pos+1).layer()) return REJECT; if (bin::all1(pos)) peaks.clear(); peaks.push_back(binhash(pos,hash)); if (deriveRoot()==root) { // bingo mass = peaks.back().first; length = mass.length(); status.resize(mass+1); bits.resize(mass+1); for(int i=0; imass) return REJECT; if (status[pos]) return bits[pos]==hash ? ACCEPT : REJECT; bits[pos] = hash; // walk to the nearest proven hash if (bits[pos.sibling()]==Sha1Hash::ZERO) return DUNNO; bin p = pos.parent(); while (!status[p]) { bits[p] = Sha1Hash(bits[p.left()],bits[p.right()]); p = p.parent(); } if ( bits[p] == Sha1Hash(bits[p.left()],bits[p.right()]) ) { for(bin i=pos; i