void TestVector(const Hasher &h, const In &in, const Out &out) { Out hash; BOOST_CHECK(out.size() == h.OUTPUT_SIZE); hash.resize(out.size()); { // Test that writing the whole input string at once works. Hasher(h).Write((unsigned char*)&in[0], in.size()).Finalize(&hash[0]); BOOST_CHECK(hash == out); } for (int i=0; i<32; i++) { // Test that writing the string broken up in random pieces works. Hasher hasher(h); size_t pos = 0; while (pos < in.size()) { size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1); hasher.Write((unsigned char*)&in[pos], len); pos += len; if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) { // Test that writing the rest at once to a copy of a hasher works. Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]); BOOST_CHECK(hash == out); } } hasher.Finalize(&hash[0]); BOOST_CHECK(hash == out); } }
/* todo: concepts... In, Out are "container-like" classes that support: ::value_type, ::size(void), ::resize(size_t), ::operator[](size_t), &::value_type (i.e. addressable ::value_type) */ Out make_copy( const In&in ) { const size_t n_ival( sizeof( typename In::value_type ) ), n_oval( sizeof( typename Out::value_type ) ); const size_t b_total( in.size() * n_ival ); const size_t size_out ( b_total / n_oval + ( ( b_total % n_oval ) ? 1 : 0 ) ); Out out; out.resize( size_out, typename Out::value_type( 0 ) ); assert ( b_total == out.size() * n_oval + ( b_total % n_oval ? 1 : 0 ) ); memcpy( &out[0], &in[0], b_total ); return out; }