Browse Source

update: using `size_t` for compatibility

master
Dnomd343 1 week ago
parent
commit
d6905aa7d6
  1. 2
      benchmark.cc
  2. 7
      src/impl/core.cc
  3. 18
      src/impl/hash_ce.inl
  4. 4
      src/impl/inline.inl
  5. 2
      src/impl/wrapper.cc
  6. 14
      src/md5.h
  7. 4
      test/helper.h
  8. 6
      test/stream.cc

2
benchmark.cc

@ -5,7 +5,7 @@ using md5::MD5;
std::string build_test_data() { std::string build_test_data() {
std::string data(65536, 0x00); std::string data(65536, 0x00);
for (uint32_t i = 0; i < data.size(); ++i) { for (size_t i = 0; i < data.size(); ++i) {
data[i] = static_cast<char>(i & 0xff); data[i] = static_cast<char>(i & 0xff);
} }
return data; return data;

7
src/impl/core.cc

@ -43,9 +43,10 @@ using md5::value::T;
static constexpr unsigned char Padding[64] { 0x80, /* 0x00, ... */ }; static constexpr unsigned char Padding[64] { 0x80, /* 0x00, ... */ };
const void* MD5::UpdateImpl(const void *data, uint64_t len) { const void* MD5::UpdateImpl(const void *data, size_t len) {
len &= ~static_cast<size_t>(0b111111); // len -> n * 64
auto *block = static_cast<const uint32_t *>(data); auto *block = static_cast<const uint32_t *>(data);
auto *limit = block + ((len &= ~0b111111ULL) >> 2); auto *limit = block + (len >> 2);
auto A = ctx_.A; auto A = ctx_.A;
auto B = ctx_.B; auto B = ctx_.B;
@ -76,7 +77,7 @@ const void* MD5::UpdateImpl(const void *data, uint64_t len) {
return limit; return limit;
} }
void MD5::FinalImpl(const void *data, uint64_t len) { void MD5::FinalImpl(const void *data, size_t len) {
if (len >= 120) { // len -> [64 + 56, INF) if (len >= 120) { // len -> [64 + 56, INF)
data = UpdateImpl(data, len); data = UpdateImpl(data, len);
len &= 0b111111; // len -> [0, 64) len &= 0b111111; // len -> [0, 64)

18
src/impl/hash_ce.inl

@ -11,28 +11,30 @@ struct md5_ctx {
struct md5_data { struct md5_data {
const char *ptr; const char *ptr;
uint64_t len, padded_len; size_t len, padded_len;
constexpr md5_data(const char *data, const uint64_t len) constexpr md5_data(const char *data, const size_t len) :
: ptr(data), len(len), padded_len((len + 64 + 8) & ~0b111111ULL) {} ptr(data), len(len),
padded_len((len + 64 + 8) & ~static_cast<size_t>(0b111111)) {}
}; };
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(const md5_data &data, const uint64_t index) { constexpr uint8_t GetByte(const md5_data &data, const size_t index) {
if (index < data.len) // message data if (index < data.len) // message data
return data.ptr[index]; return data.ptr[index];
if (index == data.len) // padding flag if (index == data.len) // padding flag
return 0x80; return 0x80;
if (index < data.padded_len - 8) // padding content if (index < data.padded_len - 8) // padding content
return 0x00; return 0x00;
const auto total = static_cast<uint64_t>(data.len * 8);
const auto offset = (index + 8 - data.padded_len) * 8; const auto offset = (index + 8 - data.padded_len) * 8;
return static_cast<uint8_t>(0xff & (data.len * 8) >> offset); return static_cast<uint8_t>((total >> offset) & 0xff);
} }
/// Get the MD5 block content at the specified index. /// Get the MD5 block content at the specified index.
constexpr Block GetBlock(const md5_data &data, const uint64_t index) { constexpr Block GetBlock(const md5_data &data, const size_t index) {
Block block {}; Block block {};
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
const auto offset = index + i * 4; const auto offset = index + i * 4;
@ -82,10 +84,10 @@ constexpr std::array<char, 32> DigestCE(const std::array<uint32_t, 4> &ctx) {
} }
/// MD5 hash implement based on constexpr. /// MD5 hash implement based on constexpr.
constexpr std::array<char, 32> Hash(const char *data, const uint64_t len) { constexpr std::array<char, 32> Hash(const char *data, const size_t len) {
md5_ctx ctx; md5_ctx ctx;
const md5_data md5 {data, len}; const md5_data md5 {data, len};
for (uint64_t index = 0; index < md5.padded_len; index += 64) { for (size_t index = 0; index < md5.padded_len; index += 64) {
const auto [A, B, C, D] = Round(GetBlock(md5, index), ctx); const auto [A, B, C, D] = Round(GetBlock(md5, index), ctx);
ctx.A += A; ctx.A += A;
ctx.B += B; ctx.B += B;

4
src/impl/inline.inl

@ -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, const uint64_t len) { inline std::string MD5::Hash(const void *data, const size_t len) {
MD5 md5; MD5 md5;
md5.FinalImpl(data, len); md5.FinalImpl(data, len);
return md5.Digest(); return md5.Digest();
@ -35,7 +35,7 @@ constexpr std::array<char, 32> MD5::HashCE(const std::string_view &data) {
return HashCE(data.data(), data.size()); return HashCE(data.data(), data.size());
} }
constexpr std::array<char, 32> MD5::HashCE(const char *data, const uint64_t len) { constexpr std::array<char, 32> MD5::HashCE(const char *data, const size_t len) {
return ce::Hash(data, len); return ce::Hash(data, len);
} }

2
src/impl/wrapper.cc

@ -13,7 +13,7 @@ std::string MD5::Digest() const {
return result; return result;
} }
MD5& MD5::Update(const void *data, uint64_t len) { MD5& MD5::Update(const void *data, size_t len) {
if (buffer_size_ != 0) { if (buffer_size_ != 0) {
if (buffer_size_ + len < 64) { // buffer not filled if (buffer_size_ + len < 64) { // buffer not filled
std::memcpy(buffer_ + buffer_size_, data, len); std::memcpy(buffer_ + buffer_size_, data, len);

14
src/md5.h

@ -35,7 +35,7 @@ public:
MD5& Update(const std::string_view &data); MD5& Update(const std::string_view &data);
/// Update md5 hash with specified data. /// Update md5 hash with specified data.
MD5_EXPORT MD5& Update(const void *data, uint64_t len); MD5_EXPORT MD5& Update(const void *data, size_t len);
/// Stop streaming updates and calculate result. /// Stop streaming updates and calculate result.
MD5& Final(); MD5& Final();
@ -47,13 +47,13 @@ public:
static std::string Hash(const std::string_view &data); static std::string Hash(const std::string_view &data);
/// Calculate the md5 hash value of the specified data. /// Calculate the md5 hash value of the specified data.
static std::string Hash(const void *data, uint64_t len); static std::string Hash(const void *data, size_t len);
/// Calculate the md5 hash value of the specified data with constexpr. /// Calculate the md5 hash value of the specified data with constexpr.
static constexpr std::array<char, 32> HashCE(const std::string_view &data); static constexpr std::array<char, 32> HashCE(const std::string_view &data);
/// Calculate the md5 hash value of the specified data with constexpr. /// Calculate the md5 hash value of the specified data with constexpr.
static constexpr std::array<char, 32> HashCE(const char *data, uint64_t len); static constexpr std::array<char, 32> HashCE(const char *data, size_t len);
private: private:
struct md5_ctx { struct md5_ctx {
@ -61,18 +61,18 @@ private:
uint32_t B = value::kB; uint32_t B = value::kB;
uint32_t C = value::kC; uint32_t C = value::kC;
uint32_t D = value::kD; uint32_t D = value::kD;
uint64_t size = 0; // processed size in byte size_t size = 0; // processed size in byte
}; };
md5_ctx ctx_; md5_ctx ctx_;
char buffer_[64] {}; char buffer_[64] {};
uint64_t buffer_size_ = 0; // size < 64 size_t buffer_size_ = 0; // size < 64
/// Update md5 ctx with specified data, and return the pointer of unprocessed data (< 64 bytes). /// Update md5 ctx with specified data, and return the pointer of unprocessed data (< 64 bytes).
const void* UpdateImpl(const void *data, uint64_t len); const void* UpdateImpl(const void *data, size_t len);
/// Update and final the md5 hash with the specified data. /// Update and final the md5 hash with the specified data.
MD5_EXPORT void FinalImpl(const void *data, uint64_t len); MD5_EXPORT void FinalImpl(const void *data, size_t len);
}; };
} // namespace md5 } // namespace md5

4
test/helper.h

@ -2,9 +2,9 @@
#include <string> #include <string>
inline std::string build_test_data(const uint32_t size) { inline std::string build_test_data(const size_t size) {
std::string data(size, 0x00); std::string data(size, 0x00);
for (uint32_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
data[i] = static_cast<char>(i); data[i] = static_cast<char>(i);
} }
return data; return data;

6
test/stream.cc

@ -8,17 +8,17 @@ TEST(md5sum, stream) {
const auto test_data = build_test_data(256 * 256); const auto test_data = build_test_data(256 * 256);
MD5 md5; MD5 md5;
for (uint32_t size = 1; size <= 256; ++size) { for (size_t size = 1; size <= 256; ++size) {
auto expect = MD5::Hash(test_data.data(), size * 256); auto expect = MD5::Hash(test_data.data(), size * 256);
for (int times = 0; times < 256; ++times) { for (size_t times = 0; times < 256; ++times) {
const auto offset = test_data.data() + times * size; const auto offset = test_data.data() + times * size;
md5.Update(offset, size); // update multiple times md5.Update(offset, size); // update multiple times
} }
EXPECT_EQ(md5.Final().Digest(), expect); EXPECT_EQ(md5.Final().Digest(), expect);
md5.Reset(); // reset for next round md5.Reset(); // reset for next round
for (int times = 0; times < 256; ++times) { for (size_t times = 0; times < 256; ++times) {
const auto offset = test_data.data() + times * size; const auto offset = test_data.data() + times * size;
md5.Update(std::string_view {offset, size}); // update multiple times md5.Update(std::string_view {offset, size}); // update multiple times
} }

Loading…
Cancel
Save