From db359ecbab2bf88197f040690cf11f69b27d6ef6 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 28 Sep 2015 18:29:03 +0100 Subject: [PATCH] Changed from generic interface inherited from ihash. --- fnv_1.h | 155 ++++++++++++++++---------------------------- hash.h | 4 +- test/test_fnv_1.cpp | 85 ++++++++++++------------ 3 files changed, 101 insertions(+), 143 deletions(-) diff --git a/fnv_1.h b/fnv_1.h index 582d1a8b..1020a123 100644 --- a/fnv_1.h +++ b/fnv_1.h @@ -34,7 +34,6 @@ SOFTWARE. #include "static_assert.h" #include "type_traits.h" -#include "endian.h" #include "ihash.h" #if defined(COMPILER_KEIL) @@ -48,11 +47,9 @@ namespace etl { //*************************************************************************** /// Calculates the fnv_1_64 hash. - ///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little. ///\ingroup fnv_1_64 //*************************************************************************** - template - class fnv_1_64 : public etl::ihash + class fnv_1_64 { public: @@ -62,7 +59,6 @@ namespace etl /// Default constructor. //************************************************************************* fnv_1_64() - : ihash(etl::endian(ENDIANNESS)) { reset(); } @@ -74,10 +70,15 @@ namespace etl //************************************************************************* template fnv_1_64(TIterator begin, const TIterator end) - : ihash(etl::endian(ENDIANNESS)) { + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + reset(); - add(begin, end); + while (begin != end) + { + hash *= PRIME; + hash ^= *begin++; + } } //************************************************************************* @@ -96,17 +97,13 @@ namespace etl template void add(TIterator begin, const TIterator end) { - ihash::add(begin, end); - } + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - //************************************************************************* - /// Adds a value. - /// \param value The value to add to the checksum. - //************************************************************************* - template - void add(TValue value) - { - ihash::add(value); + while (begin != end) + { + hash *= PRIME; + hash ^= *begin++; + } } //************************************************************************* @@ -134,14 +131,6 @@ namespace etl return hash; } - //************************************************************************* - /// Gets the generic digest value. - //************************************************************************* - generic_digest digest() - { - return ihash::get_digest(hash); - } - private: value_type hash; @@ -152,11 +141,9 @@ namespace etl //*************************************************************************** /// Calculates the fnv_1a_64 hash. - ///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little. ///\ingroup fnv_1a_64 //*************************************************************************** - template - class fnv_1a_64 : public etl::ihash + class fnv_1a_64 { public: @@ -166,7 +153,6 @@ namespace etl /// Default constructor. //************************************************************************* fnv_1a_64() - : ihash(etl::endian(ENDIANNESS)) { reset(); } @@ -178,10 +164,15 @@ namespace etl //************************************************************************* template fnv_1a_64(TIterator begin, const TIterator end) - : ihash(etl::endian(ENDIANNESS)) { + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + reset(); - add(begin, end); + while (begin != end) + { + hash ^= *begin++; + hash *= PRIME; + } } //************************************************************************* @@ -200,17 +191,13 @@ namespace etl template void add(TIterator begin, const TIterator end) { - ihash::add(begin, end); - } - - //************************************************************************* - /// Adds a value. - /// \param value The value to add to the checksum. - //************************************************************************* - template - void add(TValue value) - { - ihash::add(value); + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + + while (begin != end) + { + hash ^= *begin++; + hash *= PRIME; + } } //************************************************************************* @@ -238,14 +225,6 @@ namespace etl return hash; } - //************************************************************************* - /// Gets the generic digest value. - //************************************************************************* - generic_digest digest() - { - return ihash::get_digest(hash); - } - private: value_type hash; @@ -256,11 +235,9 @@ namespace etl //*************************************************************************** /// Calculates the fnv_1_32 hash. - ///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little. ///\ingroup fnv_1_32 //*************************************************************************** - template - class fnv_1_32 : public etl::ihash + class fnv_1_32 { public: @@ -270,7 +247,6 @@ namespace etl /// Default constructor. //************************************************************************* fnv_1_32() - : ihash(etl::endian(ENDIANNESS)) { reset(); } @@ -282,10 +258,15 @@ namespace etl //************************************************************************* template fnv_1_32(TIterator begin, const TIterator end) - : ihash(etl::endian(ENDIANNESS)) { + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + reset(); - add(begin, end); + while (begin != end) + { + hash *= PRIME; + hash ^= *begin++; + } } //************************************************************************* @@ -304,17 +285,13 @@ namespace etl template void add(TIterator begin, const TIterator end) { - ihash::add(begin, end); - } + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - //************************************************************************* - /// Adds a value. - /// \param value The value to add to the checksum. - //************************************************************************* - template - void add(TValue value) - { - ihash::add(value); + while (begin != end) + { + hash *= PRIME; + hash ^= *begin++; + } } //************************************************************************* @@ -342,14 +319,6 @@ namespace etl return hash; } - //************************************************************************* - /// Gets the generic digest value. - //************************************************************************* - generic_digest digest() - { - return ihash::get_digest(hash); - } - private: value_type hash; @@ -360,11 +329,9 @@ namespace etl //*************************************************************************** /// Calculates the fnv_1a_32 hash. - ///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little. ///\ingroup fnv_1a_32 //*************************************************************************** - template - class fnv_1a_32 : public etl::ihash + class fnv_1a_32 { public: @@ -374,7 +341,6 @@ namespace etl /// Default constructor. //************************************************************************* fnv_1a_32() - : ihash(etl::endian(ENDIANNESS)) { reset(); } @@ -386,10 +352,15 @@ namespace etl //************************************************************************* template fnv_1a_32(TIterator begin, const TIterator end) - : ihash(etl::endian(ENDIANNESS)) { + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + reset(); - add(begin, end); + while (begin != end) + { + hash ^= *begin++; + hash *= PRIME; + } } //************************************************************************* @@ -408,17 +379,13 @@ namespace etl template void add(TIterator begin, const TIterator end) { - ihash::add(begin, end); - } + STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - //************************************************************************* - /// Adds a value. - /// \param value The value to add to the checksum. - //************************************************************************* - template - void add(TValue value) - { - ihash::add(value); + while (begin != end) + { + hash ^= *begin++; + hash *= PRIME; + } } //************************************************************************* @@ -446,14 +413,6 @@ namespace etl return hash; } - //************************************************************************* - /// Gets the generic digest value. - //************************************************************************* - generic_digest digest() - { - return ihash::get_digest(hash); - } - private: value_type hash; diff --git a/hash.h b/hash.h index a373520d..01bc7259 100644 --- a/hash.h +++ b/hash.h @@ -51,7 +51,7 @@ namespace etl typename enable_if::type generic_hash(uint8_t* begin, uint8_t* end) { - return fnv_1a_32<>(begin, end); + return fnv_1a_32(begin, end); } //************************************************************************* @@ -61,7 +61,7 @@ namespace etl typename enable_if::type generic_hash(uint8_t* begin, uint8_t* end) { - return fnv_1a_64<>(begin, end); + return fnv_1a_64(begin, end); } } diff --git a/test/test_fnv_1.cpp b/test/test_fnv_1.cpp index bca22835..c953e6d5 100644 --- a/test/test_fnv_1.cpp +++ b/test/test_fnv_1.cpp @@ -33,7 +33,6 @@ SOFTWARE. #include #include "../fnv_1.h" -#include "../endian.h" namespace { @@ -44,7 +43,7 @@ namespace { std::string data("123456789"); - uint32_t hash = etl::fnv_1_32<>(data.begin(), data.end()); + uint32_t hash = etl::fnv_1_32(data.begin(), data.end()); CHECK_EQUAL(0x24148816, hash); } @@ -54,14 +53,14 @@ namespace { std::string data("123456789"); - etl::fnv_1_32<> fnv_1_32_calculator; + etl::fnv_1_32 fnv_1_32_calculator; for (size_t i = 0; i < data.size(); ++i) { - fnv_1_32_calculator += data[i]; + fnv_1_32_calculator.add(data[i]); } - uint32_t hash = fnv_1_32_calculator; + uint32_t hash = fnv_1_32_calculator.value(); CHECK_EQUAL(0x24148816, hash); } @@ -71,7 +70,7 @@ namespace { std::string data("123456789"); - etl::fnv_1_32<> fnv_1_32_calculator; + etl::fnv_1_32 fnv_1_32_calculator; fnv_1_32_calculator.add(data.begin(), data.end()); @@ -85,14 +84,14 @@ namespace { std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; std::vector data2 = { 0x04030201, 0x08070605 }; - std::vector data3 = { 0x01020304, 0x05060708 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - uint32_t hash1 = etl::fnv_1_32(data1.begin(), data1.end()); - uint32_t hash2 = etl::fnv_1_32(data2.begin(), data2.end()); - CHECK_EQUAL(hash1, hash2); + uint32_t hash1 = etl::fnv_1_32(data1.begin(), data1.end()); + uint32_t hash2 = etl::fnv_1_32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(int(hash1), int(hash2)); - uint32_t hash3 = etl::fnv_1_32(data3.begin(), data3.end()); - CHECK_EQUAL(hash1, hash3); + uint32_t hash3 = etl::fnv_1_32(data3.rbegin(), data3.rend()); + CHECK_EQUAL(int(hash1), int(hash3)); } //************************************************************************* @@ -100,7 +99,7 @@ namespace { std::string data("123456789"); - uint32_t hash = etl::fnv_1a_32<>(data.begin(), data.end()); + uint32_t hash = etl::fnv_1a_32(data.begin(), data.end()); CHECK_EQUAL(0xBB86B11C, hash); } @@ -110,14 +109,14 @@ namespace { std::string data("123456789"); - etl::fnv_1a_32<> fnv_1a_32_calculator; + etl::fnv_1a_32 fnv_1a_32_calculator; for (size_t i = 0; i < data.size(); ++i) { - fnv_1a_32_calculator += data[i]; + fnv_1a_32_calculator.add(data[i]); } - uint32_t hash = fnv_1a_32_calculator; + uint32_t hash = fnv_1a_32_calculator.value(); CHECK_EQUAL(0xBB86B11C, hash); } @@ -127,7 +126,7 @@ namespace { std::string data("123456789"); - etl::fnv_1a_32<> fnv_1a_32_calculator; + etl::fnv_1a_32 fnv_1a_32_calculator; fnv_1a_32_calculator.add(data.begin(), data.end()); @@ -141,14 +140,14 @@ namespace { std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; std::vector data2 = { 0x04030201, 0x08070605 }; - std::vector data3 = { 0x01020304, 0x05060708 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - uint32_t hash1 = etl::fnv_1a_32(data1.begin(), data1.end()); - uint32_t hash2 = etl::fnv_1a_32(data2.begin(), data2.end()); - CHECK_EQUAL(hash1, hash2); + uint32_t hash1 = etl::fnv_1a_32(data1.begin(), data1.end()); + uint32_t hash2 = etl::fnv_1a_32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(int(hash1), int(hash2)); - uint32_t hash3 = etl::fnv_1a_32(data3.begin(), data3.end()); - CHECK_EQUAL(hash1, hash3); + uint32_t hash3 = etl::fnv_1a_32(data3.rbegin(), data3.rend()); + CHECK_EQUAL(int(hash1), int(hash3)); } //************************************************************************* @@ -156,7 +155,7 @@ namespace { std::string data("123456789"); - uint64_t hash = etl::fnv_1_64<>(data.begin(), data.end()); + uint64_t hash = etl::fnv_1_64(data.begin(), data.end()); CHECK_EQUAL(0xA72FFC362BF916D6, hash); } @@ -166,11 +165,11 @@ namespace { std::string data("123456789"); - etl::fnv_1_64<> fnv_1_64_calculator; + etl::fnv_1_64 fnv_1_64_calculator; for (size_t i = 0; i < data.size(); ++i) { - fnv_1_64_calculator += data[i]; + fnv_1_64_calculator.add(data[i]); } uint64_t hash = fnv_1_64_calculator; @@ -183,7 +182,7 @@ namespace { std::string data("123456789"); - etl::fnv_1_64<> fnv_1_64_calculator; + etl::fnv_1_64 fnv_1_64_calculator; fnv_1_64_calculator.add(data.begin(), data.end()); @@ -197,14 +196,14 @@ namespace { std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; std::vector data2 = { 0x04030201, 0x08070605 }; - std::vector data3 = { 0x01020304, 0x05060708 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - uint64_t hash1 = etl::fnv_1_64(data1.begin(), data1.end()); - uint64_t hash2 = etl::fnv_1_64(data2.begin(), data2.end()); - CHECK_EQUAL(hash1, hash2); + uint64_t hash1 = etl::fnv_1_64(data1.begin(), data1.end()); + uint64_t hash2 = etl::fnv_1_64((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(int(hash1), int(hash2)); - uint64_t hash3 = etl::fnv_1_64(data3.begin(), data3.end()); - CHECK_EQUAL(hash1, hash3); + uint64_t hash3 = etl::fnv_1_64(data3.rbegin(), data3.rend()); + CHECK_EQUAL(int(hash1), int(hash3)); } //************************************************************************* @@ -212,7 +211,7 @@ namespace { std::string data("123456789"); - uint64_t hash = etl::fnv_1a_64<>(data.begin(), data.end()); + uint64_t hash = etl::fnv_1a_64(data.begin(), data.end()); CHECK_EQUAL(0x06D5573923C6CDFC, hash); } @@ -222,11 +221,11 @@ namespace { std::string data("123456789"); - etl::fnv_1a_64<> fnv_1a_64_calculator; + etl::fnv_1a_64 fnv_1a_64_calculator; for (size_t i = 0; i < data.size(); ++i) { - fnv_1a_64_calculator += data[i]; + fnv_1a_64_calculator.add(data[i]); } uint64_t hash = fnv_1a_64_calculator; @@ -239,7 +238,7 @@ namespace { std::string data("123456789"); - etl::fnv_1a_64<> fnv_1a_64_calculator; + etl::fnv_1a_64 fnv_1a_64_calculator; fnv_1a_64_calculator.add(data.begin(), data.end()); @@ -253,14 +252,14 @@ namespace { std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; std::vector data2 = { 0x04030201, 0x08070605 }; - std::vector data3 = { 0x01020304, 0x05060708 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - uint64_t hash1 = etl::fnv_1a_64(data1.begin(), data1.end()); - uint64_t hash2 = etl::fnv_1a_64(data2.begin(), data2.end()); - CHECK_EQUAL(hash1, hash2); + uint64_t hash1 = etl::fnv_1a_64(data1.begin(), data1.end()); + uint64_t hash2 = etl::fnv_1a_64((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(int(hash1), int(hash2)); - uint64_t hash3 = etl::fnv_1a_64(data3.begin(), data3.end()); - CHECK_EQUAL(hash1, hash3); + uint64_t hash3 = etl::fnv_1a_64(data3.rbegin(), data3.rend()); + CHECK_EQUAL(int(hash1), int(hash3)); } }; }