mirror of
https://github.com/ETLCPP/etl.git
synced 2026-05-01 03:19:10 +08:00
Changed from generic interface inherited from ihash.
This commit is contained in:
parent
31e828b4bb
commit
04a50d2b8a
38
checksum.h
38
checksum.h
@ -34,7 +34,6 @@ SOFTWARE.
|
||||
|
||||
#include "static_assert.h"
|
||||
#include "type_traits.h"
|
||||
#include "endian.h"
|
||||
#include "ihash.h"
|
||||
|
||||
///\defgroup checksum Checksum calculation
|
||||
@ -45,11 +44,10 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Calculates the checksum.
|
||||
///\tparam TSum The type used for the sum.
|
||||
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
|
||||
///\ingroup checksum
|
||||
//***************************************************************************
|
||||
template <typename TSum, const int ENDIANNESS = endian::little>
|
||||
class checksum : public etl::ihash
|
||||
template <typename TSum>
|
||||
class checksum
|
||||
{
|
||||
public:
|
||||
|
||||
@ -61,7 +59,6 @@ namespace etl
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
checksum()
|
||||
: ihash(etl::endian(ENDIANNESS))
|
||||
{
|
||||
reset();
|
||||
}
|
||||
@ -73,10 +70,14 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
checksum(TIterator begin, const TIterator end)
|
||||
: ihash(etl::endian(ENDIANNESS))
|
||||
{
|
||||
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
|
||||
|
||||
reset();
|
||||
add(begin, end);
|
||||
while (begin != end)
|
||||
{
|
||||
sum += *begin++;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -95,17 +96,12 @@ namespace etl
|
||||
template<typename TIterator>
|
||||
void add(TIterator begin, const TIterator end)
|
||||
{
|
||||
ihash::add(begin, end);
|
||||
}
|
||||
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a value.
|
||||
/// \param value The value to add to the checksum.
|
||||
//*************************************************************************
|
||||
template<typename TValue>
|
||||
void add(TValue value)
|
||||
{
|
||||
ihash::add(value);
|
||||
while (begin != end)
|
||||
{
|
||||
sum += *begin++;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -132,14 +128,6 @@ namespace etl
|
||||
return sum;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the generic digest value.
|
||||
//*************************************************************************
|
||||
generic_digest digest()
|
||||
{
|
||||
return ihash::get_digest(sum);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
value_type sum;
|
||||
|
||||
131
ihash.h
131
ihash.h
@ -34,9 +34,8 @@ SOFTWARE.
|
||||
#include <utility>
|
||||
|
||||
#include "exception.h"
|
||||
#include "endian.h"
|
||||
|
||||
///\defgroup ihash Base class for all hash type classes.
|
||||
///\defgroup ihash Common data for all hash type classes.
|
||||
///\ingroup hash
|
||||
|
||||
namespace etl
|
||||
@ -69,134 +68,6 @@ namespace etl
|
||||
|
||||
/// For the Americans
|
||||
typedef hash_finalised hash_finalized;
|
||||
|
||||
//***************************************************************************
|
||||
/// Hash algorithm base class.
|
||||
/// \ingroup ihash
|
||||
//***************************************************************************
|
||||
class ihash
|
||||
{
|
||||
public:
|
||||
|
||||
/// Generic return type.
|
||||
typedef std::pair<const uint8_t*, const uint8_t*> generic_digest;
|
||||
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
/// \param endianness The endianness to use for integral types larger than uint8_t.
|
||||
//*************************************************************************
|
||||
ihash(etl::endian endianness)
|
||||
: endianness(endianness)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// \param value The value to add to the hash.
|
||||
//*************************************************************************
|
||||
template<typename TValue>
|
||||
void add(TValue value)
|
||||
{
|
||||
uint8_t* p_data = reinterpret_cast<uint8_t*>(&value);
|
||||
|
||||
if (endianness == endian::little)
|
||||
{
|
||||
for (int i = 0; i < sizeof(TValue); ++i)
|
||||
{
|
||||
add(p_data[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = sizeof(TValue) - 1; i >= 0; --i)
|
||||
{
|
||||
add(p_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// \param begin Start of the range.
|
||||
/// \param end End of the range.
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
void add(TIterator begin, const TIterator end)
|
||||
{
|
||||
while (begin != end)
|
||||
{
|
||||
add(*begin);
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// \param value The value to add to the checksum.
|
||||
//*************************************************************************
|
||||
template<typename TValue>
|
||||
ihash& operator +=(TValue value)
|
||||
{
|
||||
add(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the endianness.
|
||||
//*************************************************************************
|
||||
etl::endian endian() const
|
||||
{
|
||||
return endianness;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Set the endianness.
|
||||
//*************************************************************************
|
||||
void endian(etl::endian e)
|
||||
{
|
||||
endianness = e;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// \param value The uint8_t to add to the hash.
|
||||
//*************************************************************************
|
||||
virtual void add(uint8_t value) = 0;
|
||||
|
||||
//*************************************************************************
|
||||
/// Resets the hash to the initial state.
|
||||
//*************************************************************************
|
||||
virtual void reset() = 0;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the result as a generic digest.
|
||||
//*************************************************************************
|
||||
virtual generic_digest digest() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the result as a generic digest.
|
||||
/// Templated for derived class usage.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
generic_digest get_digest(const T& hash) const
|
||||
{
|
||||
const uint8_t* begin = reinterpret_cast<const uint8_t*>(&hash);
|
||||
|
||||
return generic_digest(begin, begin + sizeof(hash));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
etl::endian endianness;
|
||||
};
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Default streaming operator.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
etl::ihash& operator << (etl::ihash& hash, T value)
|
||||
{
|
||||
hash.add(value);
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
36
pearson.h
36
pearson.h
@ -57,11 +57,10 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Calculates a Pearson hash
|
||||
///\tparam HASH_LENGTH The number of elements in the hash.
|
||||
///\tparam ENDIANNESS The endianness of the calculation for input types larger than uint8_t. Default = endian::little.
|
||||
/// \ingroup pearson
|
||||
//***************************************************************************
|
||||
template <const size_t HASH_LENGTH, const int ENDIANNESS = endian::little>
|
||||
class pearson : public etl::ihash
|
||||
template <const size_t HASH_LENGTH>
|
||||
class pearson
|
||||
{
|
||||
public:
|
||||
|
||||
@ -71,8 +70,7 @@ namespace etl
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
pearson()
|
||||
: first(true),
|
||||
ihash(etl::endian(ENDIANNESS))
|
||||
: first(true)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
@ -84,9 +82,10 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
pearson(TIterator begin, const TIterator end)
|
||||
: first(true),
|
||||
ihash(etl::endian(ENDIANNESS))
|
||||
: first(true)
|
||||
{
|
||||
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
|
||||
|
||||
reset();
|
||||
add(begin, end);
|
||||
}
|
||||
@ -107,17 +106,12 @@ namespace etl
|
||||
template<typename TIterator>
|
||||
void add(TIterator begin, const TIterator end)
|
||||
{
|
||||
ihash::add(begin, end);
|
||||
}
|
||||
STATIC_ASSERT(sizeof(typename std::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a value.
|
||||
/// \param value The value to add to the hash.
|
||||
//*************************************************************************
|
||||
template<typename TValue>
|
||||
void add(TValue value)
|
||||
{
|
||||
ihash::add(value);
|
||||
while (begin != end)
|
||||
{
|
||||
add(*begin++);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -159,14 +153,6 @@ namespace etl
|
||||
return value();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the generic digest value.
|
||||
//*************************************************************************
|
||||
generic_digest digest()
|
||||
{
|
||||
return generic_digest(etl::begin(hash), etl::end(hash));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool first;
|
||||
|
||||
@ -73,82 +73,14 @@ namespace
|
||||
|
||||
etl::checksum<uint8_t> checksum_calculator;
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
checksum_calculator += data[i];
|
||||
}
|
||||
|
||||
uint8_t sum = checksum_calculator;
|
||||
|
||||
CHECK_EQUAL(221, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_values8_operator_stream)
|
||||
{
|
||||
std::string data("123456789");
|
||||
|
||||
etl::checksum<uint8_t> checksum_calculator;
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
checksum_calculator << data[i];
|
||||
}
|
||||
|
||||
uint8_t sum = checksum_calculator;
|
||||
|
||||
CHECK_EQUAL(221, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_values32_add)
|
||||
{
|
||||
std::vector<uint32_t> data = { 0x04030201, 0x08070605 };
|
||||
|
||||
etl::checksum<uint32_t> checksum_calculator;
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
checksum_calculator += data[i];
|
||||
}
|
||||
|
||||
uint32_t sum = checksum_calculator;
|
||||
|
||||
CHECK_EQUAL(36, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_values32_plus_equals)
|
||||
{
|
||||
std::vector<uint32_t> data = { 0x04030201, 0x08070605 };
|
||||
|
||||
etl::checksum<uint32_t> checksum_calculator;
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
checksum_calculator.add(data[i]);
|
||||
}
|
||||
|
||||
uint32_t sum = checksum_calculator;
|
||||
uint8_t sum = checksum_calculator;
|
||||
|
||||
CHECK_EQUAL(36, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_values32_operator_stream)
|
||||
{
|
||||
std::vector<uint32_t> data = { 0x04030201, 0x08070605 };
|
||||
|
||||
etl::checksum<uint32_t> checksum_calculator;
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
checksum_calculator << data[i];
|
||||
}
|
||||
|
||||
uint32_t sum = checksum_calculator;
|
||||
|
||||
CHECK_EQUAL(36, int(sum));
|
||||
CHECK_EQUAL(221, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -165,6 +97,20 @@ namespace
|
||||
CHECK_EQUAL(221, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_range_sum16)
|
||||
{
|
||||
std::string data("123456789");
|
||||
|
||||
etl::checksum<uint16_t> checksum_calculator;
|
||||
|
||||
checksum_calculator.add(data.begin(), data.end());
|
||||
|
||||
uint16_t sum = checksum_calculator.value();
|
||||
|
||||
CHECK_EQUAL(477, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_range_sum32)
|
||||
{
|
||||
@ -184,58 +130,14 @@ namespace
|
||||
{
|
||||
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
|
||||
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
|
||||
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
|
||||
|
||||
uint8_t sum1 = etl::checksum<uint8_t, etl::endian::little>(data1.begin(), data1.end());
|
||||
uint8_t sum2 = etl::checksum<uint8_t, etl::endian::little>(data2.begin(), data2.end());
|
||||
CHECK_EQUAL(int(sum1), int(sum2));
|
||||
uint32_t hash1 = etl::checksum<uint32_t>(data1.begin(), data1.end());
|
||||
uint32_t hash2 = etl::checksum<uint32_t>((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
|
||||
CHECK_EQUAL(int(hash1), int(hash2));
|
||||
|
||||
uint8_t sum3 = etl::checksum<uint8_t, etl::endian::big>(data3.begin(), data3.end());
|
||||
CHECK_EQUAL(int(sum1), int(sum3));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_checksum_add_double)
|
||||
{
|
||||
double d = 3.1415927;
|
||||
|
||||
etl::checksum<uint8_t> checksum_calculator;
|
||||
|
||||
checksum_calculator << d;
|
||||
|
||||
uint8_t sum = checksum_calculator.value();
|
||||
|
||||
CHECK_EQUAL(165, int(sum));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_digest)
|
||||
{
|
||||
std::string data("123456789");
|
||||
|
||||
etl::checksum<uint8_t> checksum_calculator8(data.begin(), data.end());
|
||||
etl::checksum<uint16_t> checksum_calculator16(data.begin(), data.end());
|
||||
etl::checksum<uint32_t> checksum_calculator32(data.begin(), data.end());
|
||||
etl::checksum<uint64_t> checksum_calculator64(data.begin(), data.end());
|
||||
|
||||
etl::ihash::generic_digest digest;
|
||||
|
||||
digest = checksum_calculator8.digest();
|
||||
CHECK_EQUAL(221, *digest.first);
|
||||
CHECK_EQUAL(sizeof(uint8_t), std::distance(digest.first, digest.second));
|
||||
|
||||
digest = checksum_calculator16.digest();
|
||||
CHECK_EQUAL(477, *reinterpret_cast<const uint16_t*>(digest.first));
|
||||
CHECK_EQUAL(sizeof(uint16_t), std::distance(digest.first, digest.second));
|
||||
|
||||
|
||||
digest = checksum_calculator32.digest();
|
||||
CHECK_EQUAL(477, *reinterpret_cast<const uint32_t*>(digest.first));
|
||||
CHECK_EQUAL(sizeof(uint32_t), std::distance(digest.first, digest.second));
|
||||
|
||||
digest = checksum_calculator64.digest();
|
||||
CHECK_EQUAL(477, *reinterpret_cast<const uint64_t*>(digest.first));
|
||||
CHECK_EQUAL(sizeof(uint64_t), std::distance(digest.first, digest.second));
|
||||
uint32_t hash3 = etl::checksum<uint32_t>(data3.rbegin(), data3.rend());
|
||||
CHECK_EQUAL(int(hash1), int(hash3));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ namespace
|
||||
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
pearson_calculator += data[i];
|
||||
pearson_calculator.add(data[i]);
|
||||
}
|
||||
|
||||
hash_t compare = Pearson_Compare(data);
|
||||
@ -138,13 +138,13 @@ namespace
|
||||
{
|
||||
std::vector<uint8_t> data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
std::vector<uint32_t> data2 = { 0x04030201, 0x08070605 };
|
||||
std::vector<uint32_t> data3 = { 0x01020304, 0x05060708 };
|
||||
std::vector<uint8_t> data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
|
||||
|
||||
hash_t hash1 = etl::pearson<HASH_SIZE, etl::endian::little>(data1.begin(), data1.end());
|
||||
hash_t hash2 = etl::pearson<HASH_SIZE, etl::endian::little>(data2.begin(), data2.end());
|
||||
hash_t hash1 = etl::pearson<HASH_SIZE>(data1.begin(), data1.end());
|
||||
hash_t hash2 = etl::pearson<HASH_SIZE>((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
|
||||
CHECK_EQUAL(hash1, hash2);
|
||||
|
||||
hash_t hash3 = etl::pearson<HASH_SIZE, etl::endian::big>(data3.begin(), data3.end());
|
||||
hash_t hash3 = etl::pearson<HASH_SIZE>(data3.rbegin(), data3.rend());
|
||||
CHECK_EQUAL(hash1, hash3);
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user