[Support] Update `MD5` to follow other hashes.

Introduce `StringRef final()` and `StringRef result()`.

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D107781
This commit is contained in:
Alexandre Rames 2021-08-18 15:27:08 -07:00
parent 44a3241f10
commit cd28003336
3 changed files with 58 additions and 0 deletions

View File

@ -78,6 +78,14 @@ public:
/// Finishes off the hash and puts the result in result.
void final(MD5Result &Result);
/// Finishes off the hash, and returns a reference to the 16-byte hash data.
StringRef final();
/// Finishes off the hash, and returns a reference to the 16-byte hash data.
/// This is suitable for getting the MD5 at any time without invalidating the
/// internal state, so that more calls can be made into `update`.
StringRef result();
/// Translates the bytes in \p Res to a hex string that is
/// deposited into \p Str. The result will be of length 32.
static void stringifyResult(MD5Result &Result, SmallString<32> &Str);
@ -101,6 +109,8 @@ private:
MD5_u32plus block[16];
} InternalState;
MD5Result Result;
const uint8_t *body(ArrayRef<uint8_t> Data);
};

View File

@ -262,6 +262,23 @@ void MD5::final(MD5Result &Result) {
support::endian::write32le(&Result[12], InternalState.d);
}
StringRef MD5::final() {
final(Result);
return StringRef(reinterpret_cast<char *>(Result.Bytes.data()),
Result.Bytes.size());
}
StringRef MD5::result() {
auto StateToRestore = InternalState;
auto Hash = final();
// Restore the state
InternalState = StateToRestore;
return Hash;
}
SmallString<32> MD5::MD5Result::digest() const {
SmallString<32> Str;
raw_svector_ostream Res(Str);

View File

@ -68,4 +68,35 @@ TEST(MD5HashTest, MD5) {
EXPECT_EQ(0x3be167ca6c49fb7dULL, MD5Res.high());
EXPECT_EQ(0x00e49261d7d3fcc3ULL, MD5Res.low());
}
TEST(MD5Test, FinalAndResultHelpers) {
MD5 Hash;
Hash.update("abcd");
{
MD5 ReferenceHash;
ReferenceHash.update("abcd");
MD5::MD5Result ReferenceResult;
ReferenceHash.final(ReferenceResult);
StringRef ExpectedResult =
StringRef(reinterpret_cast<char *>(ReferenceResult.Bytes.data()),
ReferenceResult.Bytes.size());
EXPECT_EQ(Hash.result(), ExpectedResult);
}
Hash.update("xyz");
{
MD5 ReferenceHash;
ReferenceHash.update("abcd");
ReferenceHash.update("xyz");
MD5::MD5Result ReferenceResult;
ReferenceHash.final(ReferenceResult);
StringRef ExpectedResult =
StringRef(reinterpret_cast<char *>(ReferenceResult.Bytes.data()),
ReferenceResult.Bytes.size());
EXPECT_EQ(Hash.final(), ExpectedResult);
}
}
} // namespace