ENH: additional SHA1Digest constructors and methods

- data_bytes(), size_bytes() methods to support broadcasting or
  gather/scatter content. Additional construct from raw bytes
  to support transmitted content.
This commit is contained in:
Mark Olesen 2023-03-20 11:22:50 +01:00
parent 7389ce15ce
commit 622f476b32
2 changed files with 118 additions and 17 deletions

View File

@ -76,9 +76,66 @@ static unsigned char readHexDigit(Istream& is)
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
namespace
{
bool Foam::SHA1Digest::isEqual(const char* hexdigits, std::size_t len) const
// Copy assign digest from content
bool assign
(
std::array<unsigned char, 20>& digest,
const unsigned char* content,
std::size_t len
)
{
if (!content || !len)
{
return false;
}
if (len == digest.size())
{
// ie, std::copy
for (auto& val : digest)
{
val = *content;
++content;
}
return true;
}
// Skip possible '_' prefix
if (*content == '_')
{
++content;
--len;
}
// Incorrect length - can never assign
if (len != 2*digest.size())
{
return false;
}
for (auto& val : digest)
{
const unsigned char upp = *content++;
const unsigned char low = *content++;
val = (upp << 4) + low;
}
return true;
}
// Byte-wise compare digest contents
bool isEqual
(
const std::array<unsigned char, 20>& digest,
const char* hexdigits,
std::size_t len
)
{
// Skip possible '_' prefix
if (*hexdigits == '_')
@ -88,12 +145,12 @@ bool Foam::SHA1Digest::isEqual(const char* hexdigits, std::size_t len) const
}
// Incorrect length - can never match
if (len != 2*dig_.size())
if (len != 2*digest.size())
{
return false;
}
for (const auto& byteVal : dig_)
for (const auto& byteVal : digest)
{
const char upp = hexChars[((byteVal >> 4) & 0xF)];
const char low = hexChars[(byteVal & 0xF)];
@ -105,6 +162,8 @@ bool Foam::SHA1Digest::isEqual(const char* hexdigits, std::size_t len) const
return true;
}
} // End anonymous namespace
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -114,6 +173,20 @@ Foam::SHA1Digest::SHA1Digest()
}
Foam::SHA1Digest::SHA1Digest(const char* content, std::size_t len)
{
clear();
assign(dig_, reinterpret_cast<const unsigned char*>(content), len);
}
Foam::SHA1Digest::SHA1Digest(const unsigned char* content, std::size_t len)
{
clear();
assign(dig_, content, len);
}
Foam::SHA1Digest::SHA1Digest(Istream& is)
{
clear();
@ -214,7 +287,7 @@ bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
// Interpret empty string as '0000..'
size_t len = hexdigits.length();
return len ? isEqual(hexdigits.data(), len) : empty();
return len ? isEqual(dig_, hexdigits.data(), len) : empty();
}
@ -223,7 +296,7 @@ bool Foam::SHA1Digest::operator==(const char* hexdigits) const
// Interpret nullptr or empty string as '0000..'
size_t len = (hexdigits ? strlen(hexdigits) : 0);
return len ? isEqual(hexdigits, len) : empty();
return len ? isEqual(dig_, hexdigits, len) : empty();
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -68,18 +68,12 @@ class SHA1Digest
// Private Member Functions
//- Pointer to the underlying digest data
unsigned char* data()
{
return dig_.data();
}
//- Byte-wise compare digest contents
bool isEqual(const char* hexdigits, std::size_t len) const;
// Permit SHA1 to calculate the digest
friend class SHA1;
//- Raw digest data (20 bytes). Non-const access for SHA1
unsigned char* data() noexcept { return dig_.data(); }
public:
@ -94,9 +88,19 @@ public:
//- Default construct a zero digest
SHA1Digest();
//- Read construct a digest
//- Read construct a digest from stringified content
explicit SHA1Digest(Istream& is);
//- Construct digest from raw or stringified content.
//- The length is 20 for raw digest content and 40 (or 41) for
//- stringified versions.
SHA1Digest(const char* content, std::size_t len);
//- Construct digest from raw or stringified content.
//- The length is 20 for raw digest content and 40 (or 41) for
//- stringified versions.
SHA1Digest(const unsigned char* content, std::size_t len);
// Member Functions
@ -119,6 +123,30 @@ public:
Ostream& write(Ostream& os, const bool prefixed=false) const;
// Low-level access
//- Raw digest data (20 bytes) - const access
const unsigned char* cdata() const noexcept { return dig_.data(); }
//- Raw digest data (20 bytes) - const access
const unsigned char* cdata_bytes() const noexcept
{
return dig_.data();
}
//- Raw digest data (20 bytes) - non-const access. Use with caution!
unsigned char* data_bytes() noexcept
{
return dig_.data();
}
//- The number of bytes in digest (20)
static constexpr std::streamsize size_bytes() noexcept { return 20; }
//- The dimensioned size of the digest is always 20 bytes
static constexpr unsigned max_size() noexcept { return 20; }
// Member Operators
//- Equality operator