Browse Source

update: project structural adjustment

master
Dnomd343 6 months ago
parent
commit
d76adbf976
  1. 29
      src/impl/algorithm.inc
  2. 26
      src/impl/constexpr.inc
  3. 4
      src/impl/core.cc
  4. 10
      src/impl/inline.inc
  5. 48
      src/impl/value.inc
  6. 6
      src/impl/wrapper.cc

29
src/impl/algorithm.inc

@ -33,27 +33,15 @@
#define MD5_UPDATE \ #define MD5_UPDATE \
MD5_ROUND(MD5_FF) MD5_ROUND(MD5_GG) MD5_ROUND(MD5_HH) MD5_ROUND(MD5_II) MD5_ROUND(MD5_FF) MD5_ROUND(MD5_GG) MD5_ROUND(MD5_HH) MD5_ROUND(MD5_II)
#include "sine.inc" #include "value.inc"
namespace md5::impl { namespace md5::impl {
/// Hexadecimal character mapping table.
constexpr char HexTable[] = {
'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f',
};
/// MD5 fixed constants in little endian.
constexpr uint32_t MD5_A = 0x67452301;
constexpr uint32_t MD5_B = 0xefcdab89;
constexpr uint32_t MD5_C = 0x98badcfe;
constexpr uint32_t MD5_D = 0x10325476;
struct md5_ctx { struct md5_ctx {
uint32_t A = MD5_A; uint32_t A = value::kA;
uint32_t B = MD5_B; uint32_t B = value::kB;
uint32_t C = MD5_C; uint32_t C = value::kC;
uint32_t D = MD5_D; uint32_t D = value::kD;
uint64_t size = 0; // processed size in byte uint64_t size = 0; // processed size in byte
}; };
@ -77,8 +65,11 @@ constexpr int S(const int i) {
/// MD5 T-table constant, input between 0 and 63. /// MD5 T-table constant, input between 0 and 63.
constexpr uint32_t T(const int i) { constexpr uint32_t T(const int i) {
const auto val = ::md5::math::sin(i + 1); return value::kT[i];
return static_cast<uint32_t>(::md5::math::abs(val) * 0x100000000);
} }
static_assert(K(0) != K(63), "invalid constexpr");
static_assert(S(0) != S(63), "invalid constexpr");
static_assert(T(0) != T(63), "invalid constexpr");
} // namespace md5::impl } // namespace md5::impl

26
src/impl/constexpr.inc

@ -1,26 +1,24 @@
#pragma once #pragma once
#include <array>
namespace md5::impl { namespace md5::impl {
struct md5_ctx_ce { struct md5_ctx_ce {
uint32_t A = MD5_A; uint32_t A = value::kA;
uint32_t B = MD5_B; uint32_t B = value::kB;
uint32_t C = MD5_C; uint32_t C = value::kC;
uint32_t D = MD5_D; uint32_t D = value::kD;
const char *data; const char *data;
uint64_t data_len, padded_len; uint64_t data_len, padded_len;
constexpr md5_ctx_ce(const char *data, uint64_t len) constexpr md5_ctx_ce(const char *data, const uint64_t len)
: data(data), data_len(len), padded_len((len + 64 + 8) & ~0b111111ULL) {} : data(data), data_len(len), padded_len((len + 64 + 8) & ~0b111111ULL) {}
}; };
using Block = std::array<uint32_t, 16>; // single md5 block with 64 bytes using Block = std::array<uint32_t, 16>; // single md5 block with 64 bytes
/// Get the data and padding byte of the specified index. /// Get the data and padding byte of the specified index.
constexpr uint8_t GetByte(md5_ctx_ce *ctx, const uint64_t index) { constexpr uint8_t GetByte(const md5_ctx_ce *ctx, const uint64_t index) {
if (index < ctx->data_len) // message data if (index < ctx->data_len) // message data
return ctx->data[index]; return ctx->data[index];
if (index == ctx->data_len) // padding flag if (index == ctx->data_len) // padding flag
@ -32,10 +30,10 @@ constexpr uint8_t GetByte(md5_ctx_ce *ctx, const uint64_t index) {
} }
/// Get the MD5 block content at the specified index. /// Get the MD5 block content at the specified index.
constexpr Block GetBlock(md5_ctx_ce *ctx, const uint64_t index) { constexpr Block GetBlock(const md5_ctx_ce *ctx, const uint64_t index) {
Block block {}; Block block {};
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
auto offset = index + i * 4; const auto offset = index + i * 4;
(block[i] <<= 8) |= GetByte(ctx, offset + 3); (block[i] <<= 8) |= GetByte(ctx, offset + 3);
(block[i] <<= 8) |= GetByte(ctx, offset + 2); (block[i] <<= 8) |= GetByte(ctx, offset + 2);
(block[i] <<= 8) |= GetByte(ctx, offset + 1); (block[i] <<= 8) |= GetByte(ctx, offset + 1);
@ -45,13 +43,13 @@ constexpr Block GetBlock(md5_ctx_ce *ctx, const uint64_t index) {
} }
/// Convert origin MD5 integers to hexadecimal character array. /// Convert origin MD5 integers to hexadecimal character array.
constexpr std::array<char, 32> DigestCE(std::array<uint32_t, 4> ctx) { constexpr std::array<char, 32> DigestCE(const std::array<uint32_t, 4> &ctx) {
std::array<char, 32> result {}; std::array<char, 32> result {};
for (uint32_t i = 0, val = 0; i < 32; val >>= 8) { for (uint32_t i = 0, val = 0; i < 32; val >>= 8) {
if (!(i & 0b111)) if (!(i & 0b111))
val = ctx[i >> 3]; val = ctx[i >> 3];
result[i++] = HexTable[(val >> 4) & 0b1111]; result[i++] = value::HexTable[(val >> 4) & 0b1111];
result[i++] = HexTable[val & 0b1111]; result[i++] = value::HexTable[val & 0b1111];
} }
return result; return result;
} }
@ -73,4 +71,6 @@ constexpr std::array<char, 32> MD5::HashCE(const char *data, uint64_t len) {
return DigestCE({ctx.A, ctx.B, ctx.C, ctx.D}); return DigestCE({ctx.A, ctx.B, ctx.C, ctx.D});
} }
static_assert(MD5::HashCE("")[0] == 'd', "invalid constexpr");
} // namespace md5::impl } // namespace md5::impl

4
src/impl/core.cc

@ -33,7 +33,7 @@ const void* MD5::UpdateImpl(const void *data, uint64_t len) {
ctx_.C = C; ctx_.C = C;
ctx_.D = D; ctx_.D = D;
ctx_.size += len; ctx_.size += len;
return static_cast<const void *>(limit); return limit;
} }
void MD5::FinalImpl(const void *data, uint64_t len) { void MD5::FinalImpl(const void *data, uint64_t len) {
@ -44,7 +44,7 @@ void MD5::FinalImpl(const void *data, uint64_t len) {
unsigned char buffer[128]; // 2 blocks unsigned char buffer[128]; // 2 blocks
::std::memcpy(buffer, data, len); ::std::memcpy(buffer, data, len);
uint64_t total = (ctx_.size + len) << 3; // total number in bit const uint64_t total = (ctx_.size + len) << 3; // total number in bit
if (len < 56) { // len -> [0, 56) if (len < 56) { // len -> [0, 56)
::std::memcpy(buffer + len, Padding, 56 - len); ::std::memcpy(buffer + len, Padding, 56 - len);

10
src/impl/inline.inc

@ -3,10 +3,10 @@
namespace md5::impl { namespace md5::impl {
inline MD5& MD5::Reset() { inline MD5& MD5::Reset() {
ctx_.A = MD5_A; ctx_.A = value::kA;
ctx_.B = MD5_B; ctx_.B = value::kB;
ctx_.C = MD5_C; ctx_.C = value::kC;
ctx_.D = MD5_D; ctx_.D = value::kD;
ctx_.size = 0; ctx_.size = 0;
buffer_size_ = 0; buffer_size_ = 0;
return *this; return *this;
@ -25,7 +25,7 @@ inline std::string MD5::Hash(const std::string_view &data) {
return Hash(data.data(), data.size()); return Hash(data.data(), data.size());
} }
inline std::string MD5::Hash(const void *data, uint64_t len) { inline std::string MD5::Hash(const void *data, const uint64_t len) {
MD5 md5; MD5 md5;
md5.FinalImpl(data, len); md5.FinalImpl(data, len);
return md5.Digest(); return md5.Digest();

48
src/impl/value.inc

@ -0,0 +1,48 @@
#pragma once
#include "sine.inc"
namespace md5::value {
/// Hexadecimal character mapping table.
constexpr char HexTable[] = {
'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f',
};
/// MD5 fixed constants in little endian.
constexpr uint32_t kA = 0x67452301;
constexpr uint32_t kB = 0xefcdab89;
constexpr uint32_t kC = 0x98badcfe;
constexpr uint32_t kD = 0x10325476;
// In order to be compatible with C++17, the `consteval` keyword cannot be used
// here. The MD5 T-table constants will be macro-expanded and calculated.
constexpr uint32_t TCal(const int i) {
const auto val = math::sin(i + 1);
return static_cast<uint32_t>(math::abs(val) * 0x100000000);
}
#define MD5_TT \
MD5_T(00) MD5_T(01) MD5_T(02) MD5_T(03) MD5_T(04) MD5_T(05) MD5_T(06) MD5_T(07) \
MD5_T(08) MD5_T(09) MD5_T(0a) MD5_T(0b) MD5_T(0c) MD5_T(0d) MD5_T(0e) MD5_T(0f) \
MD5_T(10) MD5_T(11) MD5_T(12) MD5_T(13) MD5_T(14) MD5_T(15) MD5_T(16) MD5_T(17) \
MD5_T(18) MD5_T(19) MD5_T(1a) MD5_T(1b) MD5_T(1c) MD5_T(1d) MD5_T(1e) MD5_T(1f) \
MD5_T(20) MD5_T(21) MD5_T(22) MD5_T(23) MD5_T(24) MD5_T(25) MD5_T(26) MD5_T(27) \
MD5_T(28) MD5_T(29) MD5_T(2a) MD5_T(2b) MD5_T(2c) MD5_T(2d) MD5_T(2e) MD5_T(2f) \
MD5_T(30) MD5_T(31) MD5_T(32) MD5_T(33) MD5_T(34) MD5_T(35) MD5_T(36) MD5_T(37) \
MD5_T(38) MD5_T(39) MD5_T(3a) MD5_T(3b) MD5_T(3c) MD5_T(3d) MD5_T(3e) MD5_T(3f)
#define MD5_T(x) constexpr auto kT_##x = TCal(0x##x);
MD5_TT
#undef MD5_T
#define MD5_T(x) kT_##x,
/// MD5 T-table constant array.
constexpr std::array kT = {MD5_TT};
#undef MD5_T
#undef MD5_TT
} // namespace md5::value

6
src/impl/wrapper.cc

@ -8,8 +8,8 @@ std::string MD5::Digest() const {
std::string result(32, 0x00); std::string result(32, 0x00);
auto *ptr = reinterpret_cast<const uint8_t *>(&ctx_); auto *ptr = reinterpret_cast<const uint8_t *>(&ctx_);
for (int i = 0; i < 32; ++ptr) { for (int i = 0; i < 32; ++ptr) {
result[i++] = HexTable[*ptr >> 4]; result[i++] = value::HexTable[*ptr >> 4];
result[i++] = HexTable[*ptr & 0b1111]; result[i++] = value::HexTable[*ptr & 0b1111];
} }
return result; return result;
} }
@ -22,7 +22,7 @@ MD5& MD5::Update(const void *data, uint64_t len) {
return *this; // save into buffer and return return *this; // save into buffer and return
} }
auto size = 64 - buffer_size_; const auto size = 64 - buffer_size_;
::std::memcpy(buffer_ + buffer_size_, data, size); ::std::memcpy(buffer_ + buffer_size_, data, size);
UpdateImpl(buffer_, 64); // fill and update with buffer UpdateImpl(buffer_, 64); // fill and update with buffer
data = static_cast<const char*>(data) + size; data = static_cast<const char*>(data) + size;

Loading…
Cancel
Save