Browse Source

update: using `size_t` for compatibility

master
Dnomd343 2 months 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 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);
}
return data;

7
src/impl/core.cc

@ -43,9 +43,10 @@ using md5::value::T;
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 *limit = block + ((len &= ~0b111111ULL) >> 2);
auto *limit = block + (len >> 2);
auto A = ctx_.A;
auto B = ctx_.B;
@ -76,7 +77,7 @@ const void* MD5::UpdateImpl(const void *data, uint64_t len) {
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)
data = UpdateImpl(data, len);
len &= 0b111111; // len -> [0, 64)

18
src/impl/hash_ce.inl

@ -11,28 +11,30 @@ struct md5_ctx {
struct md5_data {
const char *ptr;
uint64_t len, padded_len;
size_t len, padded_len;
constexpr md5_data(const char *data, const uint64_t len)
: ptr(data), len(len), padded_len((len + 64 + 8) & ~0b111111ULL) {}
constexpr md5_data(const char *data, const size_t len) :
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
/// 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
return data.ptr[index];
if (index == data.len) // padding flag
return 0x80;
if (index < data.padded_len - 8) // padding content
return 0x00;
const auto total = static_cast<uint64_t>(data.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.
constexpr Block GetBlock(const md5_data &data, const uint64_t index) {
constexpr Block GetBlock(const md5_data &data, const size_t index) {
Block block {};
for (int i = 0; i < 16; ++i) {
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.
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;
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);
ctx.A += A;
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());
}
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.FinalImpl(data, len);
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());
}
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);
}

2
src/impl/wrapper.cc

@ -13,7 +13,7 @@ std::string MD5::Digest() const {
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_ + len < 64) { // buffer not filled
std::memcpy(buffer_ + buffer_size_, data, len);

14
src/md5.h

@ -35,7 +35,7 @@ public:
MD5& Update(const std::string_view &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.
MD5& Final();
@ -47,13 +47,13 @@ public:
static std::string Hash(const std::string_view &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.
static constexpr std::array<char, 32> HashCE(const std::string_view &data);
/// 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:
struct md5_ctx {
@ -61,18 +61,18 @@ private:
uint32_t B = value::kB;
uint32_t C = value::kC;
uint32_t D = value::kD;
uint64_t size = 0; // processed size in byte
size_t size = 0; // processed size in byte
};
md5_ctx ctx_;
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).
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.
MD5_EXPORT void FinalImpl(const void *data, uint64_t len);
MD5_EXPORT void FinalImpl(const void *data, size_t len);
};
} // namespace md5

4
test/helper.h

@ -2,9 +2,9 @@
#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);
for (uint32_t i = 0; i < size; ++i) {
for (size_t i = 0; i < size; ++i) {
data[i] = static_cast<char>(i);
}
return data;

6
test/stream.cc

@ -8,17 +8,17 @@ TEST(md5sum, stream) {
const auto test_data = build_test_data(256 * 256);
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);
for (int times = 0; times < 256; ++times) {
for (size_t times = 0; times < 256; ++times) {
const auto offset = test_data.data() + times * size;
md5.Update(offset, size); // update multiple times
}
EXPECT_EQ(md5.Final().Digest(), expect);
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;
md5.Update(std::string_view {offset, size}); // update multiple times
}

Loading…
Cancel
Save