mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add checksum/md5, sum, xor
This commit is contained in:
parent
30241d3be6
commit
f05cd35fe8
12 changed files with 863 additions and 174 deletions
70
sprout/bit/length.hpp
Normal file
70
sprout/bit/length.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#ifndef SPROUT_BIT_LENGTH_HPP
|
||||
#define SPROUT_BIT_LENGTH_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t bit_len_8_table[std::size_t(UCHAR_MAX) + 1] = {
|
||||
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
|
||||
};
|
||||
template<std::size_t Size>
|
||||
struct bit_len {
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size - 1;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT;
|
||||
private:
|
||||
template <typename IntType>
|
||||
SPROUT_CONSTEXPR IntType impl(IntType x, unsigned char i) const {
|
||||
return bit_len_8_table[i]
|
||||
? bit_len_8_table[i] + next_size * CHAR_BIT
|
||||
: sprout::detail::bit_len<next_size>().template operator()(x)
|
||||
;
|
||||
}
|
||||
public:
|
||||
template <typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return impl(x, static_cast<unsigned char>((x >> shift_bits) & UCHAR_MAX));
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct bit_len<1> {
|
||||
public:
|
||||
template<typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return bit_len_8_table[static_cast<unsigned char>(x & UCHAR_MAX)];
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
//
|
||||
// bit_length
|
||||
//
|
||||
template<typename IntType>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
std::is_integral<IntType>::value,
|
||||
IntType
|
||||
>::type bit_length(IntType x) {
|
||||
return sprout::detail::bit_len<sizeof(IntType)>().template operator()(x);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_LENGTH_HPP
|
|
@ -5,5 +5,8 @@
|
|||
#include <sprout/bit/popcount.hpp>
|
||||
#include <sprout/bit/clz.hpp>
|
||||
#include <sprout/bit/ctz.hpp>
|
||||
#include <sprout/bit/rotate.hpp>
|
||||
#include <sprout/bit/reverse.hpp>
|
||||
#include <sprout/bit/length.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_OPERATION_HPP
|
||||
|
|
81
sprout/bit/reverse.hpp
Normal file
81
sprout/bit/reverse.hpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef SPROUT_BIT_REVERSE_HPP
|
||||
#define SPROUT_BIT_REVERSE_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
SPROUT_STATIC_CONSTEXPR unsigned char bit_rev_8_table[std::size_t(UCHAR_MAX) + 1] = {
|
||||
0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200,
|
||||
40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228,
|
||||
20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220,
|
||||
60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
|
||||
10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198,
|
||||
38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238,
|
||||
30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209,
|
||||
49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
|
||||
5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205,
|
||||
45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227,
|
||||
19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219,
|
||||
59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
|
||||
15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
|
||||
};
|
||||
template<std::size_t Size>
|
||||
struct bit_rev {
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size / 2;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT;
|
||||
public:
|
||||
template <typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return (sprout::detail::bit_rev<next_size>().template operator()(x) << shift_bits)
|
||||
| (sprout::detail::bit_rev<next_size>().template operator()(x >> shift_bits))
|
||||
;
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct bit_rev<1> {
|
||||
public:
|
||||
template<typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return sprout::detail::bit_rev_8_table[static_cast<unsigned char>(x & UCHAR_MAX)];
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
//
|
||||
// bit_reverse
|
||||
//
|
||||
template<typename IntType>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
std::is_integral<IntType>::value,
|
||||
IntType
|
||||
>::type bit_reverse(IntType x) {
|
||||
typedef typename std::make_unsigned<IntType>::type unsigned_type;
|
||||
return static_cast<IntType>(
|
||||
sprout::detail::bit_rev<sizeof(IntType)>().template operator()<unsigned_type>(x)
|
||||
);
|
||||
}
|
||||
//
|
||||
// bit_reverse_in
|
||||
//
|
||||
template <typename IntType>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
std::is_integral<IntType>::value,
|
||||
IntType
|
||||
>::type bit_reverse_in(IntType x, std::size_t length) {
|
||||
typedef typename std::make_unsigned<IntType>::type unsigned_type;
|
||||
return length <= sizeof(IntType) * CHAR_BIT
|
||||
? static_cast<IntType>(
|
||||
sprout::detail::bit_rev<sizeof(IntType)>().template operator()<unsigned_type>(x)
|
||||
>> (sizeof(IntType) * CHAR_BIT - length)
|
||||
)
|
||||
: throw std::invalid_argument("invalid length")
|
||||
;
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_REVERSE_HPP
|
30
sprout/bit/rotate.hpp
Normal file
30
sprout/bit/rotate.hpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef SPROUT_BIT_ROTATE_HPP
|
||||
#define SPROUT_BIT_ROTATE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <climits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// left_rotate
|
||||
//
|
||||
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
left_rotate(T x, std::size_t n) {
|
||||
return (x << n) ^ (x >> (sizeof(T) * CHAR_BIT - n));
|
||||
}
|
||||
|
||||
//
|
||||
// right_rotate
|
||||
//
|
||||
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR T
|
||||
right_rotate(T x, std::size_t n) {
|
||||
return (x >> n) ^ (x << (sizeof(T) * CHAR_BIT - n));
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_ROTATE_HPP
|
|
@ -2,6 +2,9 @@
|
|||
#define SPROUT_CHECKSUM_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/checksum/sum.hpp>
|
||||
#include <sprout/checksum/xor.hpp>
|
||||
#include <sprout/checksum/md5.hpp>
|
||||
#include <sprout/checksum/sha1.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_CHECKSUM_HPP
|
||||
|
|
452
sprout/checksum/md5.hpp
Normal file
452
sprout/checksum/md5.hpp
Normal file
|
@ -0,0 +1,452 @@
|
|||
#ifndef SPROUT_CHECKSUM_MD5_HPP
|
||||
#define SPROUT_CHECKSUM_MD5_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <climits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/bytes_iterator.hpp>
|
||||
#include <sprout/operation/fixed/set.hpp>
|
||||
#include <sprout/bit/rotate.hpp>
|
||||
#include <sprout/bit/reverse.hpp>
|
||||
|
||||
namespace sprout {
|
||||
static_assert(CHAR_BIT == 8, "CHAR_BIT == 8");
|
||||
|
||||
namespace md5_detail {
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
func_f(std::uint32_t x, std::uint32_t y, std::uint32_t z) {
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
func_g(std::uint32_t x, std::uint32_t y, std::uint32_t z) {
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
func_h(std::uint32_t x, std::uint32_t y, std::uint32_t z) {
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
func_i(std::uint32_t x, std::uint32_t y, std::uint32_t z) {
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
struct round1_op {
|
||||
public:
|
||||
SPROUT_CONSTEXPR std::uint32_t
|
||||
operator()(std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, std::uint32_t t, std::uint32_t s) const {
|
||||
return b + sprout::left_rotate(a + sprout::md5_detail::func_f(b, c, d) + x + t, s);
|
||||
}
|
||||
};
|
||||
struct round2_op {
|
||||
public:
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
operator()(std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, std::uint32_t t, std::uint32_t s) const {
|
||||
return b + sprout::left_rotate(a + sprout::md5_detail::func_g(b, c, d) + x + t, s);
|
||||
}
|
||||
};
|
||||
struct round3_op {
|
||||
public:
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
operator()(std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, std::uint32_t t, std::uint32_t s) const {
|
||||
return b + sprout::left_rotate(a + sprout::md5_detail::func_h(b, c, d) + x + t, s);
|
||||
}
|
||||
};
|
||||
struct round4_op {
|
||||
public:
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
operator()(std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, std::uint32_t t, std::uint32_t s) const {
|
||||
return b + sprout::left_rotate(a + sprout::md5_detail::func_i(b, c, d) + x + t, s);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RoundOp>
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round_x_impl(
|
||||
std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t d, sprout::array<std::uint32_t, 16> const& x, RoundOp round_op,
|
||||
sprout::array<std::size_t, 16> const& xis, sprout::array<std::uint32_t, 16> const& ts, sprout::array<std::uint32_t, 16> const& ss,
|
||||
std::size_t i = 0
|
||||
)
|
||||
{
|
||||
return i == 16 ? sprout::array<std::uint32_t, 4>{{a, b, c, d}}
|
||||
: i % 4 == 0 ? sprout::md5_detail::round_x_impl(round_op(a, b, c, d, x[xis[i]], ts[i], ss[i]), b, c, d, x, round_op, xis, ts, ss, i + 1)
|
||||
: i % 4 == 1 ? sprout::md5_detail::round_x_impl(a, b, c, round_op(d, a, b, c, x[xis[i]], ts[i], ss[i]), x, round_op, xis, ts, ss, i + 1)
|
||||
: i % 4 == 2 ? sprout::md5_detail::round_x_impl(a, b, round_op(c, d, a, b, x[xis[i]], ts[i], ss[i]), d, x, round_op, xis, ts, ss, i + 1)
|
||||
: sprout::md5_detail::round_x_impl(a, round_op(b, c, d, a, x[xis[i]], ts[i], ss[i]), c, d, x, round_op, xis, ts, ss, i + 1)
|
||||
;
|
||||
}
|
||||
template<typename RoundOp>
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round_x(
|
||||
sprout::array<std::uint32_t, 4> const& k, sprout::array<std::uint32_t, 16> const& x, RoundOp round_op,
|
||||
sprout::array<std::size_t, 16> const& xis, sprout::array<std::uint32_t, 16> const& ts, sprout::array<std::uint32_t, 16> const& ss
|
||||
)
|
||||
{
|
||||
return sprout::md5_detail::round_x_impl(k[0], k[1], k[2], k[3], x, round_op, xis, ts, ss);
|
||||
}
|
||||
|
||||
template<int N>
|
||||
struct round_table;
|
||||
|
||||
# define SPROUT_MD5_DETAIL_ROUND_TABLE_DEF(N, XIS, TS, SS) \
|
||||
template<> \
|
||||
struct round_table<N> { \
|
||||
public: \
|
||||
typedef sprout::array<std::size_t, 16> xis_type; \
|
||||
typedef sprout::array<std::uint32_t, 16> ts_type; \
|
||||
typedef sprout::array<std::uint32_t, 16> ss_type; \
|
||||
public: \
|
||||
SPROUT_STATIC_CONSTEXPR xis_type xis \
|
||||
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(XIS) \
|
||||
; \
|
||||
SPROUT_STATIC_CONSTEXPR ts_type ts \
|
||||
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(TS) \
|
||||
; \
|
||||
SPROUT_STATIC_CONSTEXPR ss_type ss \
|
||||
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(SS) \
|
||||
; \
|
||||
}; \
|
||||
SPROUT_CONSTEXPR_OR_CONST typename sprout::md5_detail::round_table<N>::xis_type sprout::md5_detail::round_table<N>::xis \
|
||||
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(XIS) \
|
||||
; \
|
||||
SPROUT_CONSTEXPR_OR_CONST typename sprout::md5_detail::round_table<N>::ts_type sprout::md5_detail::round_table<N>::ts \
|
||||
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(TS) \
|
||||
; \
|
||||
SPROUT_CONSTEXPR_OR_CONST typename sprout::md5_detail::round_table<N>::ss_type sprout::md5_detail::round_table<N>::ss \
|
||||
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(SS)
|
||||
|
||||
SPROUT_MD5_DETAIL_ROUND_TABLE_DEF( \
|
||||
1, \
|
||||
(xis_type{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}), \
|
||||
(ts_type{{ \
|
||||
0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, \
|
||||
0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821 \
|
||||
}}), \
|
||||
(ss_type{{7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22}}) \
|
||||
);
|
||||
SPROUT_MD5_DETAIL_ROUND_TABLE_DEF( \
|
||||
2, \
|
||||
(xis_type{{1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12}}), \
|
||||
(ts_type{{ \
|
||||
0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, \
|
||||
0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A \
|
||||
}}), \
|
||||
(ss_type{{5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20}}) \
|
||||
);
|
||||
SPROUT_MD5_DETAIL_ROUND_TABLE_DEF( \
|
||||
3, \
|
||||
(xis_type{{5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2}}), \
|
||||
(ts_type{{ \
|
||||
0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, \
|
||||
0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665 \
|
||||
}}), \
|
||||
(ss_type{{4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23}}) \
|
||||
);
|
||||
SPROUT_MD5_DETAIL_ROUND_TABLE_DEF( \
|
||||
4, \
|
||||
(xis_type{{0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9}}), \
|
||||
(ts_type{{ \
|
||||
0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, \
|
||||
0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 \
|
||||
}}), \
|
||||
(ss_type{{6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}}) \
|
||||
);
|
||||
# undef SPROUT_MD5_DETAIL_ROUND_TABLE_DEF
|
||||
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round1(sprout::array<std::uint32_t, 4> const& k, sprout::array<std::uint32_t, 16> const& x) {
|
||||
return sprout::md5_detail::round_x(
|
||||
k, x, sprout::md5_detail::round1_op(),
|
||||
sprout::md5_detail::round_table<1>::xis,
|
||||
sprout::md5_detail::round_table<1>::ts,
|
||||
sprout::md5_detail::round_table<1>::ss
|
||||
);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round2(sprout::array<std::uint32_t, 4> const& k, sprout::array<std::uint32_t, 16> const& x) {
|
||||
return sprout::md5_detail::round_x(
|
||||
k, x, sprout::md5_detail::round2_op(),
|
||||
sprout::md5_detail::round_table<2>::xis,
|
||||
sprout::md5_detail::round_table<2>::ts,
|
||||
sprout::md5_detail::round_table<2>::ss
|
||||
);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round3(sprout::array<std::uint32_t, 4> const& k, sprout::array<std::uint32_t, 16> const& x) {
|
||||
return sprout::md5_detail::round_x(
|
||||
k, x, sprout::md5_detail::round3_op(),
|
||||
sprout::md5_detail::round_table<3>::xis,
|
||||
sprout::md5_detail::round_table<3>::ts,
|
||||
sprout::md5_detail::round_table<3>::ss
|
||||
);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round4(sprout::array<std::uint32_t, 4> const& k, sprout::array<std::uint32_t, 16> const& x) {
|
||||
return sprout::md5_detail::round_x(
|
||||
k, x, sprout::md5_detail::round4_op(),
|
||||
sprout::md5_detail::round_table<4>::xis,
|
||||
sprout::md5_detail::round_table<4>::ts,
|
||||
sprout::md5_detail::round_table<4>::ss
|
||||
);
|
||||
}
|
||||
|
||||
inline SPROUT_CONSTEXPR sprout::array<std::uint32_t, 4>
|
||||
round_all(sprout::array<std::uint32_t, 4> const& k, sprout::array<std::uint32_t, 16> const& x) {
|
||||
return sprout::md5_detail::round4(
|
||||
sprout::md5_detail::round3(
|
||||
sprout::md5_detail::round2(
|
||||
sprout::md5_detail::round1(k, x),
|
||||
x
|
||||
),
|
||||
x
|
||||
),
|
||||
x
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// md5
|
||||
//
|
||||
class md5 {
|
||||
public:
|
||||
typedef sprout::array<std::uint8_t, 16> value_type;
|
||||
typedef md5 const const_type;
|
||||
private:
|
||||
sprout::array<std::uint32_t, 4> k_;
|
||||
sprout::array<std::uint32_t, 16> block_;
|
||||
std::uint64_t bit_count_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR md5(
|
||||
sprout::array<std::uint32_t, 4> const& k,
|
||||
std::uint64_t bit_count
|
||||
)
|
||||
: k_(k)
|
||||
, block_{{}}
|
||||
, bit_count_(bit_count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR md5(
|
||||
sprout::array<std::uint32_t, 4> const& k,
|
||||
sprout::array<std::uint32_t, 16> const& block,
|
||||
std::uint64_t bit_count
|
||||
)
|
||||
: k_(k)
|
||||
, block_(block)
|
||||
, bit_count_(bit_count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR md5 const process(
|
||||
sprout::array<std::uint32_t, 4> const& k,
|
||||
sprout::array<std::uint32_t, 16> const& block,
|
||||
std::uint64_t bit_count
|
||||
) const
|
||||
{
|
||||
return bit_count % (64 * 8) != 0 ? const_type(k, block, bit_count)
|
||||
: const_type(k, block, bit_count).process_block()
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_block_1(sprout::array<std::uint32_t, 4> const& x) const {
|
||||
return md5(
|
||||
sprout::array<std::uint32_t, 4>{{k_[0] + x[0], k_[1] + x[1], k_[2] + x[2], k_[3] + x[3]}},
|
||||
bit_count_
|
||||
);
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_block() const {
|
||||
return process_block_1(sprout::md5_detail::round_all(k_, block_));
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_bit_impl(bool bit, std::size_t index, std::size_t offset) const {
|
||||
return process(
|
||||
k_,
|
||||
sprout::fixed::set(
|
||||
block_,
|
||||
block_.begin() + index,
|
||||
block_[index] | static_cast<std::uint32_t>(bit) << (offset / 8 * 8 + (7 - offset % 8))
|
||||
),
|
||||
bit_count_ + 1
|
||||
);
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_bits_impl(std::uint8_t bits, std::size_t i) const {
|
||||
return i == 0 ? *this
|
||||
: process_bit(((bits >> (i - 1)) & 1) != 0).process_bits_impl(bits, i - 1)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_byte_impl(std::uint8_t byte, std::size_t index, std::size_t offset) const {
|
||||
return process(
|
||||
k_,
|
||||
sprout::fixed::set(
|
||||
block_,
|
||||
block_.begin() + index,
|
||||
block_[index]
|
||||
| static_cast<std::uint32_t>(((byte >> 7) & 1) != 0) << (offset / 8 * 8 + (7 - offset % 8))
|
||||
| static_cast<std::uint32_t>(((byte >> 6) & 1) != 0) << ((offset + 1) / 8 * 8 + (7 - (offset + 1) % 8))
|
||||
| static_cast<std::uint32_t>(((byte >> 5) & 1) != 0) << ((offset + 2) / 8 * 8 + (7 - (offset + 2) % 8))
|
||||
| static_cast<std::uint32_t>(((byte >> 4) & 1) != 0) << ((offset + 3) / 8 * 8 + (7 - (offset + 3) % 8))
|
||||
| static_cast<std::uint32_t>(((byte >> 3) & 1) != 0) << ((offset + 4) / 8 * 8 + (7 - (offset + 4) % 8))
|
||||
| static_cast<std::uint32_t>(((byte >> 2) & 1) != 0) << ((offset + 5) / 8 * 8 + (7 - (offset + 5) % 8))
|
||||
| static_cast<std::uint32_t>(((byte >> 1) & 1) != 0) << ((offset + 6) / 8 * 8 + (7 - (offset + 6) % 8))
|
||||
| static_cast<std::uint32_t>((byte & 1) != 0) << ((offset + 7) / 8 * 8 + (7 - (offset + 7) % 8))
|
||||
),
|
||||
bit_count_ + 8
|
||||
);
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR md5 const process_block_impl(Iterator first, Iterator last) const {
|
||||
return first == last ? *this
|
||||
: process_byte(*first).process_block_impl(sprout::next(first), last)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR std::uint64_t pad_size() const {
|
||||
return static_cast<std::size_t>((511 + 448 - bit_count_) % 512);
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_padding(std::uint64_t pad_size) const {
|
||||
return pad_size == 0 ? *this
|
||||
: process_bit(false).process_padding(pad_size - 1)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_length(std::uint64_t bit_count) const {
|
||||
return process_byte(static_cast<std::uint8_t>(bit_count & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 8) & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 16) & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 24) & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 32) & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 40) & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 48) & 0xFF))
|
||||
.process_byte(static_cast<std::uint8_t>((bit_count >> 56) & 0xFF))
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR value_type make_value() const {
|
||||
return value_type{{
|
||||
static_cast<std::uint8_t>((k_[0]) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[0] >> 8) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[0] >> 16) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[0] >> 24) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[1]) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[1] >> 8) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[1] >> 16) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[1] >> 24) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[2]) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[2] >> 8) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[2] >> 16) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[2] >> 24) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[3]) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[3] >> 8) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[3] >> 16) & 0xFF),
|
||||
static_cast<std::uint8_t>((k_[3] >> 24) & 0xFF)
|
||||
}};
|
||||
}
|
||||
void process_block() {
|
||||
sprout::array<std::uint32_t, 4> x = sprout::md5_detail::round_all(k_, block_);
|
||||
k_[0] += x[0];
|
||||
k_[1] += x[1];
|
||||
k_[2] += x[2];
|
||||
k_[3] += x[3];
|
||||
block_.assign(0);
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_block_impl(Iterator first, Iterator last) {
|
||||
for(; first != last; ++first) {
|
||||
process_byte(*first);
|
||||
}
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR md5()
|
||||
: k_{{0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476}}
|
||||
, block_{{}}
|
||||
, bit_count_()
|
||||
{}
|
||||
void reset() {
|
||||
k_[0] = 0x67452301;
|
||||
k_[1] = 0xEFCDAB89;
|
||||
k_[2] = 0x98BADCFE;
|
||||
k_[3] = 0x10325476;
|
||||
block_.assign(0);
|
||||
bit_count_ = 0;
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR md5 const process_bit(bool bit) const {
|
||||
return process_bit_impl(
|
||||
bit,
|
||||
static_cast<std::size_t>(bit_count_ % (64 * 8) / 32),
|
||||
static_cast<std::size_t>(bit_count_ % 32)
|
||||
);
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_bits(std::uint8_t bits, std::size_t bit_count) {
|
||||
return process_bits_impl(bits, bit_count);
|
||||
}
|
||||
SPROUT_CONSTEXPR md5 const process_byte(std::uint8_t byte) const {
|
||||
return bit_count_ % 8 == 0 ? process_byte_impl(
|
||||
byte,
|
||||
static_cast<std::size_t>(bit_count_ % (64 * 8) / 32),
|
||||
static_cast<std::size_t>(bit_count_ % 32)
|
||||
)
|
||||
: process_bit(((byte >> 7) & 1) != 0)
|
||||
.process_bit(((byte >> 6) & 1) != 0)
|
||||
.process_bit(((byte >> 5) & 1) != 0)
|
||||
.process_bit(((byte >> 4) & 1) != 0)
|
||||
.process_bit(((byte >> 3) & 1) != 0)
|
||||
.process_bit(((byte >> 2) & 1) != 0)
|
||||
.process_bit(((byte >> 1) & 1) != 0)
|
||||
.process_bit((byte & 1) != 0)
|
||||
;
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR md5 const process_block(Iterator bytes_begin, Iterator bytes_end) const {
|
||||
return process_block_impl(
|
||||
sprout::make_bytes_iterator(bytes_begin),
|
||||
sprout::make_bytes_iterator(bytes_end)
|
||||
);
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR md5 const process_bytes(Iterator buffer, std::size_t byte_count) const {
|
||||
return process_block(buffer, sprout::next(buffer, byte_count));
|
||||
}
|
||||
template<typename Range>
|
||||
SPROUT_CONSTEXPR md5 const process_range(Range const& bytes_range) const {
|
||||
return process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
|
||||
}
|
||||
|
||||
void process_bit(bool bit) {
|
||||
std::size_t index = static_cast<std::size_t>(bit_count_ % (64 * 8) / 32);
|
||||
std::size_t offset = static_cast<std::size_t>(bit_count_ % 32);
|
||||
block_[index] |= static_cast<std::uint32_t>(bit) << (offset / 8 * 8 + (7 - offset % 8));
|
||||
if (++bit_count_ % 512 == 0) {
|
||||
process_block();
|
||||
}
|
||||
}
|
||||
void process_bits(std::uint8_t bits, std::size_t bit_count) {
|
||||
while (bit_count--) {
|
||||
process_bit(((bits >> bit_count) & 1) != 0);
|
||||
}
|
||||
}
|
||||
void process_byte(std::uint8_t byte) {
|
||||
process_bits(byte, 8);
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_block(Iterator bytes_begin, Iterator bytes_end) {
|
||||
process_block_impl(
|
||||
sprout::make_bytes_iterator(bytes_begin),
|
||||
sprout::make_bytes_iterator(bytes_end)
|
||||
);
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_bytes(Iterator buffer, std::size_t byte_count) {
|
||||
process_block(buffer, sprout::next(buffer, byte_count));
|
||||
}
|
||||
template<typename Range>
|
||||
void process_range(Range const& bytes_range) {
|
||||
process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR value_type checksum() const {
|
||||
return process_bit(true).process_padding(pad_size()).process_length(bit_count_).make_value();
|
||||
}
|
||||
SPROUT_CONSTEXPR value_type operator()() const {
|
||||
return checksum();
|
||||
}
|
||||
};
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CHECKSUM_MD5_HPP
|
|
@ -6,7 +6,6 @@
|
|||
#include <climits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/index_tuple.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/sub_array.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
|
@ -15,23 +14,18 @@
|
|||
#include <sprout/algorithm/fixed/fill.hpp>
|
||||
#include <sprout/range/algorithm/fixed/copy.hpp>
|
||||
#include <sprout/operation/fixed/set.hpp>
|
||||
#include <sprout/bit/rotate.hpp>
|
||||
|
||||
namespace sprout {
|
||||
static_assert(CHAR_BIT == 8, "CHAR_BIT == 8");
|
||||
|
||||
namespace detail {
|
||||
inline SPROUT_CONSTEXPR std::uint32_t
|
||||
sha1_left_rotate(std::uint32_t x, std::size_t n) {
|
||||
return (x << n) ^ (x >> (32 - n));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// sha1
|
||||
//
|
||||
class sha1 {
|
||||
public:
|
||||
typedef sprout::array<std::uint8_t, 20> value_type;
|
||||
typedef sha1 const const_type;
|
||||
private:
|
||||
sprout::array<std::uint32_t, 5> h_;
|
||||
sprout::array<std::uint8_t, 64> block_;
|
||||
|
@ -55,7 +49,7 @@ namespace sprout {
|
|||
| (block_[i * 4 + 1] << 16)
|
||||
| (block_[i * 4 + 2] << 8)
|
||||
| (block_[i * 4 + 3])
|
||||
: sprout::detail::sha1_left_rotate(
|
||||
: sprout::left_rotate(
|
||||
calc_w(i - 3) ^ calc_w(i - 8) ^ calc_w(i - 14) ^ calc_w(i - 16),
|
||||
1
|
||||
)
|
||||
|
@ -69,18 +63,8 @@ namespace sprout {
|
|||
) const
|
||||
{
|
||||
return block_byte_index != 64
|
||||
? sha1(
|
||||
h,
|
||||
block,
|
||||
block_byte_index,
|
||||
bit_count
|
||||
)
|
||||
: sha1(
|
||||
h,
|
||||
block,
|
||||
0,
|
||||
bit_count
|
||||
).process_block_0()
|
||||
? const_type(h, block, block_byte_index, bit_count)
|
||||
: const_type(h, block, 0, bit_count).process_block()
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR sha1 const process_block_2(
|
||||
|
@ -95,9 +79,9 @@ namespace sprout {
|
|||
) const
|
||||
{
|
||||
return process_block_1(
|
||||
sprout::detail::sha1_left_rotate(a, 5) + f + e + k + calc_w(i),
|
||||
sprout::left_rotate(a, 5) + f + e + k + calc_w(i),
|
||||
a,
|
||||
sprout::detail::sha1_left_rotate(b, 30),
|
||||
sprout::left_rotate(b, 30),
|
||||
c,
|
||||
d,
|
||||
i + 1
|
||||
|
@ -138,7 +122,7 @@ namespace sprout {
|
|||
)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR sha1 const process_block_0() const {
|
||||
SPROUT_CONSTEXPR sha1 const process_block() const {
|
||||
return process_block_1(h_[0], h_[1], h_[2], h_[3], h_[4]);
|
||||
}
|
||||
template<typename Iterator, typename... Args>
|
||||
|
@ -224,7 +208,7 @@ namespace sprout {
|
|||
)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR sha1 const process_append() const {
|
||||
SPROUT_CONSTEXPR sha1 const process_length() const {
|
||||
return process(
|
||||
h_,
|
||||
sprout::get_internal(sprout::range::fixed::copy(
|
||||
|
@ -277,7 +261,7 @@ namespace sprout {
|
|||
w[i] |= (block_[i * 4 + 3]);
|
||||
}
|
||||
for (std::size_t i = 16; i < 80; ++i) {
|
||||
w[i] = sprout::detail::sha1_left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
||||
w[i] = sprout::left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
||||
}
|
||||
std::uint32_t a = h_[0];
|
||||
std::uint32_t b = h_[1];
|
||||
|
@ -300,10 +284,10 @@ namespace sprout {
|
|||
f = b ^ c ^ d;
|
||||
k = 0xCA62C1D6;
|
||||
}
|
||||
unsigned temp = sprout::detail::sha1_left_rotate(a, 5) + f + e + k + w[i];
|
||||
unsigned temp = sprout::left_rotate(a, 5) + f + e + k + w[i];
|
||||
e = d;
|
||||
d = c;
|
||||
c = sprout::detail::sha1_left_rotate(b, 30);
|
||||
c = sprout::left_rotate(b, 30);
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
|
@ -320,6 +304,12 @@ namespace sprout {
|
|||
process_block();
|
||||
}
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_block_impl(Iterator first, Iterator last) {
|
||||
for(; first != last; ++first) {
|
||||
process_byte(*first);
|
||||
}
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR sha1()
|
||||
: h_{{0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}}
|
||||
|
@ -327,6 +317,15 @@ namespace sprout {
|
|||
, block_byte_index_()
|
||||
, bit_count_()
|
||||
{}
|
||||
void reset() {
|
||||
h_[0] = 0x67452301;
|
||||
h_[1] = 0xEFCDAB89;
|
||||
h_[2] = 0x98BADCFE;
|
||||
h_[3] = 0x10325476;
|
||||
h_[4] = 0xC3D2E1F0;
|
||||
block_byte_index_ = 0;
|
||||
bit_count_ = 0;
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR sha1 const process_byte(std::uint8_t byte) const {
|
||||
return process(
|
||||
|
@ -358,9 +357,10 @@ namespace sprout {
|
|||
}
|
||||
template<typename Iterator>
|
||||
void process_block(Iterator bytes_begin, Iterator bytes_end) {
|
||||
for(; bytes_begin != bytes_end; ++bytes_begin) {
|
||||
process_byte(*bytes_begin);
|
||||
}
|
||||
process_block_impl(
|
||||
sprout::make_bytes_iterator(bytes_begin),
|
||||
sprout::make_bytes_iterator(bytes_end)
|
||||
);
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_bytes(Iterator buffer, std::size_t byte_count) {
|
||||
|
@ -372,7 +372,7 @@ namespace sprout {
|
|||
}
|
||||
|
||||
SPROUT_CONSTEXPR value_type checksum() const {
|
||||
return process_one().process_padding().process_append().make_value();
|
||||
return process_one().process_padding().process_length().make_value();
|
||||
}
|
||||
SPROUT_CONSTEXPR value_type operator()() const {
|
||||
return checksum();
|
||||
|
|
104
sprout/checksum/sum.hpp
Normal file
104
sprout/checksum/sum.hpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
#ifndef SPROUT_CHECKSUM_SUM_HPP
|
||||
#define SPROUT_CHECKSUM_SUM_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <climits>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/bytes_iterator.hpp>
|
||||
#include <sprout/numeric/accumulate.hpp>
|
||||
#include <sprout/detail/integer.hpp>
|
||||
|
||||
namespace sprout {
|
||||
static_assert(CHAR_BIT == 8, "CHAR_BIT == 8");
|
||||
|
||||
//
|
||||
// sum_basic
|
||||
//
|
||||
template<std::size_t Bits = 8>
|
||||
class sum_basic {
|
||||
static_assert(Bits % 8 == 0, "Bits % 8 == 0");
|
||||
public:
|
||||
typedef typename sprout::detail::uint_t<Bits>::least value_type;
|
||||
typedef sum_basic const const_type;
|
||||
typedef typename std::conditional<
|
||||
sizeof(std::size_t) < sizeof(value_type),
|
||||
value_type,
|
||||
std::size_t
|
||||
>::type sum_type;
|
||||
private:
|
||||
sum_type sum_;
|
||||
private:
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR sum_type calc_sum(Iterator first, Iterator last) const {
|
||||
return sprout::accumulate(
|
||||
sprout::make_bytes_iterator(first),
|
||||
sprout::make_bytes_iterator(last),
|
||||
sum_
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR sum_basic() = default;
|
||||
SPROUT_CONSTEXPR sum_basic(sum_basic const&) = default;
|
||||
explicit SPROUT_CONSTEXPR sum_basic(sum_type sum)
|
||||
: sum_(sum)
|
||||
{}
|
||||
void reset(sum_type new_sum = 0) {
|
||||
sum_ = new_sum;
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR sum_basic const process_byte(std::uint8_t byte) const {
|
||||
return sum_basic(sum_ + byte);
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR sum_basic const process_block(Iterator bytes_begin, Iterator bytes_end) const {
|
||||
return sum_basic(calc_sum(bytes_begin, bytes_end));
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR sum_basic const process_bytes(Iterator buffer, std::size_t byte_count) const {
|
||||
return process_block(buffer, sprout::next(buffer, byte_count));
|
||||
}
|
||||
template<typename Range>
|
||||
SPROUT_CONSTEXPR sum_basic const process_range(Range const& bytes_range) const {
|
||||
return process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
|
||||
}
|
||||
|
||||
void process_byte(std::uint8_t byte) {
|
||||
sum_ += byte;
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_block(Iterator bytes_begin, Iterator bytes_end) {
|
||||
sum_ = calc_sum(bytes_begin, bytes_end);
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_bytes(Iterator buffer, std::size_t byte_count) {
|
||||
process_block(buffer, sprout::next(buffer, byte_count));
|
||||
}
|
||||
template<typename Range>
|
||||
void process_range(Range const& bytes_range) {
|
||||
process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR value_type checksum() const {
|
||||
return static_cast<value_type>(sum_ & std::numeric_limits<value_type>::max());
|
||||
}
|
||||
SPROUT_CONSTEXPR value_type operator()() const {
|
||||
return checksum();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// sum8
|
||||
// sum16
|
||||
// sum32
|
||||
//
|
||||
typedef sprout::sum_basic<8> sum8;
|
||||
typedef sprout::sum_basic<16> sum16;
|
||||
typedef sprout::sum_basic<32> sum32;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CHECKSUM_SUM_HPP
|
84
sprout/checksum/xor.hpp
Normal file
84
sprout/checksum/xor.hpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef SPROUT_CHECKSUM_XOR_HPP
|
||||
#define SPROUT_CHECKSUM_XOR_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/bytes_iterator.hpp>
|
||||
#include <sprout/numeric/accumulate.hpp>
|
||||
#include <sprout/functional/polymorphic/bit_xor.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// xor8
|
||||
//
|
||||
class xor8 {
|
||||
public:
|
||||
typedef std::uint8_t value_type;
|
||||
typedef xor8 const const_type;
|
||||
typedef std::size_t sum_type;
|
||||
private:
|
||||
sum_type sum_;
|
||||
private:
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR sum_type calc_sum(Iterator first, Iterator last) const {
|
||||
return sprout::accumulate(
|
||||
sprout::make_bytes_iterator(first),
|
||||
sprout::make_bytes_iterator(last),
|
||||
sum_,
|
||||
sprout::bit_xor_
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR xor8(xor8 const&) = default;
|
||||
explicit SPROUT_CONSTEXPR xor8(sum_type sum)
|
||||
: sum_(sum)
|
||||
{}
|
||||
void reset(sum_type new_sum = 0) {
|
||||
sum_ = new_sum;
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR xor8 const process_byte(std::uint8_t byte) const {
|
||||
return xor8(sum_ ^ byte);
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR xor8 const process_block(Iterator bytes_begin, Iterator bytes_end) const {
|
||||
return xor8(calc_sum(bytes_begin, bytes_end));
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR xor8 const process_bytes(Iterator buffer, std::size_t byte_count) const {
|
||||
return process_block(buffer, sprout::next(buffer, byte_count));
|
||||
}
|
||||
template<typename Range>
|
||||
SPROUT_CONSTEXPR xor8 const process_range(Range const& bytes_range) const {
|
||||
return process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
|
||||
}
|
||||
|
||||
void process_byte(std::uint8_t byte) {
|
||||
sum_ ^= byte;
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_block(Iterator bytes_begin, Iterator bytes_end) {
|
||||
sum_ = calc_sum(bytes_begin, bytes_end);
|
||||
}
|
||||
template<typename Iterator>
|
||||
void process_bytes(Iterator buffer, std::size_t byte_count) {
|
||||
process_block(buffer, sprout::next(buffer, byte_count));
|
||||
}
|
||||
template<typename Range>
|
||||
void process_range(Range const& bytes_range) {
|
||||
process_block(sprout::begin(bytes_range), sprout::end(bytes_range));
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR value_type checksum() const {
|
||||
return static_cast<value_type>(sum_ & 0xFF);
|
||||
}
|
||||
SPROUT_CONSTEXPR value_type operator()() const {
|
||||
return checksum();
|
||||
}
|
||||
};
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_CHECKSUM_XOR_HPP
|
|
@ -1,70 +1,7 @@
|
|||
#ifndef SPROUT_INTEGER_BIT_LENGTH_HPP
|
||||
#define SPROUT_INTEGER_BIT_LENGTH_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t bit_len_8_table[std::size_t(UCHAR_MAX) + 1] = {
|
||||
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
|
||||
};
|
||||
template<std::size_t Size>
|
||||
struct bit_len {
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size - 1;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT;
|
||||
private:
|
||||
template <typename IntType>
|
||||
SPROUT_CONSTEXPR IntType impl(IntType x, unsigned char i) const {
|
||||
return bit_len_8_table[i]
|
||||
? bit_len_8_table[i] + next_size * CHAR_BIT
|
||||
: sprout::detail::bit_len<next_size>().template operator()(x)
|
||||
;
|
||||
}
|
||||
public:
|
||||
template <typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return impl(x, static_cast<unsigned char>((x >> shift_bits) & UCHAR_MAX));
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct bit_len<1> {
|
||||
public:
|
||||
template<typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return bit_len_8_table[static_cast<unsigned char>(x & UCHAR_MAX)];
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
//
|
||||
// bit_length
|
||||
//
|
||||
template<typename IntType>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
std::is_integral<IntType>::value,
|
||||
IntType
|
||||
>::type bit_length(IntType x) {
|
||||
return sprout::detail::bit_len<sizeof(IntType)>().template operator()(x);
|
||||
}
|
||||
} // namespace sprout
|
||||
#include <sprout/bit/length.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_INTEGER_BIT_LENGTH_HPP
|
||||
|
|
|
@ -1,81 +1,7 @@
|
|||
#ifndef SPROUT_INTEGER_BIT_REVERSE_HPP
|
||||
#define SPROUT_INTEGER_BIT_REVERSE_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
SPROUT_STATIC_CONSTEXPR unsigned char bit_rev_8_table[std::size_t(UCHAR_MAX) + 1] = {
|
||||
0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200,
|
||||
40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228,
|
||||
20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220,
|
||||
60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
|
||||
10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198,
|
||||
38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238,
|
||||
30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209,
|
||||
49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
|
||||
5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205,
|
||||
45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227,
|
||||
19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219,
|
||||
59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
|
||||
15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
|
||||
};
|
||||
template<std::size_t Size>
|
||||
struct bit_rev {
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size / 2;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT;
|
||||
public:
|
||||
template <typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return (sprout::detail::bit_rev<next_size>().template operator()(x) << shift_bits)
|
||||
| (sprout::detail::bit_rev<next_size>().template operator()(x >> shift_bits))
|
||||
;
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct bit_rev<1> {
|
||||
public:
|
||||
template<typename IntType>
|
||||
SPROUT_CONSTEXPR IntType operator()(IntType x) const {
|
||||
return sprout::detail::bit_rev_8_table[static_cast<unsigned char>(x & UCHAR_MAX)];
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
//
|
||||
// bit_reverse
|
||||
//
|
||||
template<typename IntType>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
std::is_integral<IntType>::value,
|
||||
IntType
|
||||
>::type bit_reverse(IntType x) {
|
||||
typedef typename std::make_unsigned<IntType>::type unsigned_type;
|
||||
return static_cast<IntType>(
|
||||
sprout::detail::bit_rev<sizeof(IntType)>().template operator()<unsigned_type>(x)
|
||||
);
|
||||
}
|
||||
//
|
||||
// bit_reverse_in
|
||||
//
|
||||
template <typename IntType>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
std::is_integral<IntType>::value,
|
||||
IntType
|
||||
>::type bit_reverse_in(IntType x, std::size_t length) {
|
||||
typedef typename std::make_unsigned<IntType>::type unsigned_type;
|
||||
return length <= sizeof(IntType) * CHAR_BIT
|
||||
? static_cast<IntType>(
|
||||
sprout::detail::bit_rev<sizeof(IntType)>().template operator()<unsigned_type>(x)
|
||||
>> (sizeof(IntType) * CHAR_BIT - length)
|
||||
)
|
||||
: throw std::invalid_argument("invalid length")
|
||||
;
|
||||
}
|
||||
} // namespace sprout
|
||||
#include <sprout/bit/reverse.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_INTEGER_BIT_REVERSE_HPP
|
||||
|
|
|
@ -15,7 +15,6 @@ namespace sprout {
|
|||
public:
|
||||
typedef sprout::uuids::uuid result_type;
|
||||
private:
|
||||
typedef sprout::sha1 const sha1_const_type;
|
||||
typedef typename result_type::value_type value_type;
|
||||
private:
|
||||
sprout::sha1 sha_;
|
||||
|
@ -45,10 +44,10 @@ namespace sprout {
|
|||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR name_generator()
|
||||
: sha_(sha1_const_type().process_range(sprout::uuids::uuid{{0}}))
|
||||
: sha_(sprout::sha1::const_type().process_range(sprout::uuids::uuid{{0}}))
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR name_generator(sprout::uuids::uuid const& namespace_uuid)
|
||||
: sha_(sha1_const_type().process_range(namespace_uuid))
|
||||
: sha_(sprout::sha1::const_type().process_range(namespace_uuid))
|
||||
{}
|
||||
template<typename Elem, std::size_t N, typename Traits>
|
||||
SPROUT_CONSTEXPR result_type operator()(sprout::basic_string<Elem, N, Traits> const& name) const {
|
||||
|
|
Loading…
Reference in a new issue