mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: modernize SHA1 classes (#1301)
- localize some functionality, std::array for digest internals. Additional append sub-string methods, pass-through write of digest etc.
This commit is contained in:
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
@ -36,9 +36,8 @@ Description
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "SHA1.H"
|
#include "SHA1.H"
|
||||||
#include "IOstreams.H"
|
|
||||||
#include "endian.H"
|
#include "endian.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -77,17 +76,17 @@ static inline void set_uint32(unsigned char *dst, uint32_t v)
|
|||||||
|
|
||||||
void Foam::SHA1::processBytes(const void *data, size_t len)
|
void Foam::SHA1::processBytes(const void *data, size_t len)
|
||||||
{
|
{
|
||||||
// already finalized, thus need to restart from nothing
|
// Already finalized, thus need to restart from nothing
|
||||||
if (finalized_)
|
if (finalized_)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// complete filling of internal buffer
|
// Complete filling of internal buffer
|
||||||
if (bufLen_)
|
if (bufLen_)
|
||||||
{
|
{
|
||||||
size_t remaining = bufLen_;
|
const size_t remaining = bufLen_;
|
||||||
size_t add =
|
const size_t add =
|
||||||
(
|
(
|
||||||
sizeof(buffer_) - remaining > len
|
sizeof(buffer_) - remaining > len
|
||||||
? len
|
? len
|
||||||
@ -158,10 +157,10 @@ void Foam::SHA1::processBytes(const void *data, size_t len)
|
|||||||
void Foam::SHA1::processBlock(const void *data, size_t len)
|
void Foam::SHA1::processBlock(const void *data, size_t len)
|
||||||
{
|
{
|
||||||
const uint32_t *words = reinterpret_cast<const uint32_t*>(data);
|
const uint32_t *words = reinterpret_cast<const uint32_t*>(data);
|
||||||
size_t nwords = len / sizeof(uint32_t);
|
const size_t nwords = len / sizeof(uint32_t);
|
||||||
const uint32_t *endp = words + nwords;
|
const uint32_t *endp = words + nwords;
|
||||||
|
|
||||||
// calculate with sixteen words of 32-bits
|
// Calculate with sixteen words of 32-bits
|
||||||
uint32_t x[16];
|
uint32_t x[16];
|
||||||
uint32_t a = hashsumA_;
|
uint32_t a = hashsumA_;
|
||||||
uint32_t b = hashsumB_;
|
uint32_t b = hashsumB_;
|
||||||
@ -295,7 +294,7 @@ void Foam::SHA1::calcDigest(SHA1Digest& dig) const
|
|||||||
{
|
{
|
||||||
if (bufTotal_[0] || bufTotal_[1])
|
if (bufTotal_[0] || bufTotal_[1])
|
||||||
{
|
{
|
||||||
unsigned char *r = dig.v_;
|
unsigned char *r = dig.data();
|
||||||
|
|
||||||
set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
|
set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
|
||||||
set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
|
set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
|
||||||
@ -305,8 +304,7 @@ void Foam::SHA1::calcDigest(SHA1Digest& dig) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no data!
|
dig.clear(); // No data!
|
||||||
dig.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,24 +332,24 @@ bool Foam::SHA1::finalize()
|
|||||||
{
|
{
|
||||||
finalized_ = true;
|
finalized_ = true;
|
||||||
|
|
||||||
// account for unprocessed bytes
|
// Account for unprocessed bytes
|
||||||
uint32_t bytes = bufLen_;
|
const uint32_t bytes = bufLen_;
|
||||||
size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
|
const size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
|
||||||
|
|
||||||
// count remaining bytes.
|
// Count remaining bytes.
|
||||||
bufTotal_[0] += bytes;
|
bufTotal_[0] += bytes;
|
||||||
if (bufTotal_[0] < bytes)
|
if (bufTotal_[0] < bytes)
|
||||||
{
|
{
|
||||||
++bufTotal_[1];
|
++bufTotal_[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalized, but no data!
|
// Finalized, but no data!
|
||||||
if (!bufTotal_[0] && !bufTotal_[1])
|
if (!bufTotal_[0] && !bufTotal_[1])
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// place the 64-bit file length in *bits* at the end of the buffer.
|
// Place the 64-bit length in *bits* at the end of the buffer.
|
||||||
buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29));
|
buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29));
|
||||||
buffer_[size-1] = swapBytes(bufTotal_[0] << 3);
|
buffer_[size-1] = swapBytes(bufTotal_[0] << 3);
|
||||||
|
|
||||||
@ -367,28 +365,6 @@ bool Foam::SHA1::finalize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::SHA1Digest Foam::SHA1::digest() const
|
|
||||||
{
|
|
||||||
SHA1Digest dig;
|
|
||||||
|
|
||||||
if (finalized_)
|
|
||||||
{
|
|
||||||
calcDigest(dig);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// avoid disturbing our data - use a copy
|
|
||||||
SHA1 sha(*this);
|
|
||||||
if (sha.finalize())
|
|
||||||
{
|
|
||||||
sha.calcDigest(dig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dig;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#undef K1
|
#undef K1
|
||||||
|
|||||||
@ -45,9 +45,7 @@ SourceFiles
|
|||||||
#define SHA1_H
|
#define SHA1_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstddef>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "int.H"
|
|
||||||
#include "SHA1Digest.H"
|
#include "SHA1Digest.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -61,7 +59,7 @@ namespace Foam
|
|||||||
|
|
||||||
class SHA1
|
class SHA1
|
||||||
{
|
{
|
||||||
// Private data
|
// Private Data
|
||||||
|
|
||||||
//- Track if the hashsum has been finalized (added count, etc)
|
//- Track if the hashsum has been finalized (added count, etc)
|
||||||
bool finalized_;
|
bool finalized_;
|
||||||
@ -91,8 +89,9 @@ class SHA1
|
|||||||
//- Process for the next LEN bytes, LEN need not be a multiple of 64.
|
//- Process for the next LEN bytes, LEN need not be a multiple of 64.
|
||||||
void processBytes(const void *data, size_t len);
|
void processBytes(const void *data, size_t len);
|
||||||
|
|
||||||
//- Calculate current digest from appended data.
|
//- Calculate digest from current data.
|
||||||
void calcDigest(SHA1Digest&) const;
|
void calcDigest(SHA1Digest& dig) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -101,41 +100,60 @@ public:
|
|||||||
//- Construct null
|
//- Construct null
|
||||||
inline SHA1();
|
inline SHA1();
|
||||||
|
|
||||||
//- Construct null and append initial std::string
|
|
||||||
inline explicit SHA1(const std::string&);
|
|
||||||
|
|
||||||
//- Construct null and append initial string
|
//- Construct null and append initial string
|
||||||
inline explicit SHA1(const char*);
|
inline explicit SHA1(const char* str);
|
||||||
|
|
||||||
|
//- Construct null and append initial std::string
|
||||||
|
inline explicit SHA1(const std::string& str);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Reset the hashed data before appending more
|
//- Reset the hashed data before appending more
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
//- Append data for processing
|
||||||
|
inline SHA1& append(const char* str);
|
||||||
|
|
||||||
//- Append data for processing
|
//- Append data for processing
|
||||||
inline SHA1& append(const char* data, size_t len);
|
inline SHA1& append(const char* data, size_t len);
|
||||||
|
|
||||||
//- Append string for processing
|
//- Append string for processing
|
||||||
inline SHA1& append(const std::string&);
|
inline SHA1& append(const std::string& str);
|
||||||
|
|
||||||
//- Append string for processing
|
//- Append substring for processing
|
||||||
inline SHA1& append(const char* str);
|
inline SHA1& append
|
||||||
|
(
|
||||||
|
const std::string& str,
|
||||||
|
size_t pos,
|
||||||
|
size_t len = std::string::npos
|
||||||
|
);
|
||||||
|
|
||||||
//- Finalized the calculations (normally not needed directly).
|
//- Finalized the calculations (normally not needed directly).
|
||||||
// Returns false if no bytes were passed for processing
|
// Returns false if no bytes were passed for processing
|
||||||
bool finalize();
|
bool finalize();
|
||||||
|
|
||||||
//- Calculate current digest from appended data.
|
//- Calculate digest from current data.
|
||||||
SHA1Digest digest() const;
|
inline SHA1Digest digest() const;
|
||||||
|
|
||||||
|
//- The digest (40-byte) text representation, optionally with '_' prefix
|
||||||
|
inline std::string str(const bool prefixed=false) const;
|
||||||
|
|
||||||
|
//- Write digest (40-byte) representation, optionally with '_' prefix
|
||||||
|
inline Ostream& write(Ostream& os, const bool prefixed=false) const;
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
|
//- Cast conversion to a SHA1Digest,
|
||||||
|
// calculates the %digest from the current data
|
||||||
|
inline operator SHA1Digest() const;
|
||||||
|
|
||||||
//- Equality operator, compares %digests
|
//- Equality operator, compares %digests
|
||||||
inline bool operator==(const SHA1&) const;
|
inline bool operator==(const SHA1& rhs) const;
|
||||||
|
|
||||||
//- Compare %digest
|
//- Compare %digest
|
||||||
inline bool operator==(const SHA1Digest&) const;
|
inline bool operator==(const SHA1Digest& dig) const;
|
||||||
|
|
||||||
//- Compare %digest to (40-byte) text representation (eg, from sha1sum)
|
//- Compare %digest to (40-byte) text representation (eg, from sha1sum)
|
||||||
// An %empty string is equivalent to
|
// An %empty string is equivalent to
|
||||||
@ -147,7 +165,6 @@ public:
|
|||||||
// "0000000000000000000000000000000000000000"
|
// "0000000000000000000000000000000000000000"
|
||||||
inline bool operator==(const char* hexdigits) const;
|
inline bool operator==(const char* hexdigits) const;
|
||||||
|
|
||||||
|
|
||||||
//- Inequality operator, compares %digests
|
//- Inequality operator, compares %digests
|
||||||
inline bool operator!=(const SHA1&) const;
|
inline bool operator!=(const SHA1&) const;
|
||||||
|
|
||||||
@ -159,11 +176,6 @@ public:
|
|||||||
|
|
||||||
//- Inequality operator, compare %digest
|
//- Inequality operator, compare %digest
|
||||||
inline bool operator!=(const char* hexdigits) const;
|
inline bool operator!=(const char* hexdigits) const;
|
||||||
|
|
||||||
|
|
||||||
//- Convert to a SHA1Digest,
|
|
||||||
// calculate current %digest from appended data
|
|
||||||
inline operator SHA1Digest() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011-2015 OpenFOAM Foundation
|
| Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
@ -27,29 +27,30 @@ License
|
|||||||
|
|
||||||
#include "SHA1Digest.H"
|
#include "SHA1Digest.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const Foam::SHA1Digest Foam::SHA1Digest::null;
|
const Foam::SHA1Digest Foam::SHA1Digest::null;
|
||||||
|
|
||||||
//! \cond fileScope
|
|
||||||
static const char hexChars[] = "0123456789abcdef";
|
static const char hexChars[] = "0123456789abcdef";
|
||||||
//! \endcond
|
|
||||||
|
// The char '0' == 0
|
||||||
|
static constexpr int offsetZero = int('0');
|
||||||
|
|
||||||
|
// The char 'A' (or 'a') == 10
|
||||||
|
static constexpr int offsetUpper = int('A') - 10;
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
unsigned char Foam::SHA1Digest::readHexDigit(Istream& is)
|
namespace Foam
|
||||||
{
|
{
|
||||||
// Takes into account that 'a' (or 'A') is 10
|
|
||||||
static const int alphaOffset = toupper('A') - 10;
|
|
||||||
// Takes into account that '0' is 0
|
|
||||||
static const int zeroOffset = int('0');
|
|
||||||
|
|
||||||
|
// Read hexadecimal value, ignoring leading or intermediate '_'
|
||||||
// silently ignore leading or intermediate '_'
|
static unsigned char readHexDigit(Istream& is)
|
||||||
|
{
|
||||||
|
// Silently ignore leading or intermediate '_'
|
||||||
char c = 0;
|
char c = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -57,23 +58,22 @@ unsigned char Foam::SHA1Digest::readHexDigit(Istream& is)
|
|||||||
}
|
}
|
||||||
while (c == '_');
|
while (c == '_');
|
||||||
|
|
||||||
if (!isxdigit(c))
|
if (isdigit(c))
|
||||||
|
{
|
||||||
|
return int(c) - offsetZero;
|
||||||
|
}
|
||||||
|
else if (!isxdigit(c))
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "Illegal hex digit: '" << c << "'"
|
<< "Illegal hex digit: '" << c << "'"
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isdigit(c))
|
return toupper(c) - offsetUpper;
|
||||||
{
|
|
||||||
return int(c) - zeroOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return toupper(c) - alphaOffset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -85,7 +85,8 @@ Foam::SHA1Digest::SHA1Digest()
|
|||||||
|
|
||||||
Foam::SHA1Digest::SHA1Digest(Istream& is)
|
Foam::SHA1Digest::SHA1Digest(Istream& is)
|
||||||
{
|
{
|
||||||
is >> *this;
|
clear();
|
||||||
|
read(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,15 +94,15 @@ Foam::SHA1Digest::SHA1Digest(Istream& is)
|
|||||||
|
|
||||||
void Foam::SHA1Digest::clear()
|
void Foam::SHA1Digest::clear()
|
||||||
{
|
{
|
||||||
memset(v_, 0, length);
|
dig_.fill(0); // Same as memset(dig_.data(), 0, dig_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::SHA1Digest::empty() const
|
bool Foam::SHA1Digest::empty() const
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < length; ++i)
|
for (const auto& byteVal : dig_)
|
||||||
{
|
{
|
||||||
if (v_[i])
|
if (byteVal)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -118,24 +119,39 @@ std::string Foam::SHA1Digest::str(const bool prefixed) const
|
|||||||
|
|
||||||
if (prefixed)
|
if (prefixed)
|
||||||
{
|
{
|
||||||
buf.resize(1 + length*2);
|
buf.resize(1 + 2*dig_.size());
|
||||||
buf[nChar++] = '_';
|
buf[nChar++] = '_';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf.resize(length*2);
|
buf.resize(2*dig_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; ++i)
|
for (const auto& byteVal : dig_)
|
||||||
{
|
{
|
||||||
buf[nChar++] = hexChars[((v_[i] >> 4) & 0xF)];
|
buf[nChar++] = hexChars[((byteVal >> 4) & 0xF)]; // Upper nibble
|
||||||
buf[nChar++] = hexChars[(v_[i] & 0xF)];
|
buf[nChar++] = hexChars[(byteVal & 0xF)]; // Lower nibble
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Istream& Foam::SHA1Digest::read(Istream& is)
|
||||||
|
{
|
||||||
|
for (auto& byteVal : dig_)
|
||||||
|
{
|
||||||
|
const unsigned char upp = readHexDigit(is);
|
||||||
|
const unsigned char low = readHexDigit(is);
|
||||||
|
|
||||||
|
byteVal = (upp << 4) + low;
|
||||||
|
}
|
||||||
|
|
||||||
|
is.check(FUNCTION_NAME);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
|
Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
|
||||||
{
|
{
|
||||||
if (prefixed)
|
if (prefixed)
|
||||||
@ -143,10 +159,10 @@ Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
|
|||||||
os.write('_');
|
os.write('_');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; ++i)
|
for (const auto& byteVal : dig_)
|
||||||
{
|
{
|
||||||
os.write(hexChars[((v_[i] >> 4) & 0xF)]);
|
os.write(hexChars[((byteVal >> 4) & 0xF)]); // Upper nibble
|
||||||
os.write(hexChars[(v_[i] & 0xF)]);
|
os.write(hexChars[(byteVal & 0xF)]); // Lower nibble
|
||||||
}
|
}
|
||||||
|
|
||||||
os.check(FUNCTION_NAME);
|
os.check(FUNCTION_NAME);
|
||||||
@ -158,46 +174,38 @@ Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
|
|||||||
|
|
||||||
bool Foam::SHA1Digest::operator==(const SHA1Digest& rhs) const
|
bool Foam::SHA1Digest::operator==(const SHA1Digest& rhs) const
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < length; ++i)
|
return (dig_ == rhs.dig_);
|
||||||
{
|
|
||||||
if (v_[i] != rhs.v_[i])
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
|
bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
|
||||||
{
|
{
|
||||||
// null or empty string is not an error - interpret as '0000..'
|
// Null or empty string is not an error - interpret as '0000..'
|
||||||
if (hexdigits.empty())
|
if (hexdigits.empty())
|
||||||
{
|
{
|
||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip possible '_' prefix
|
// Skip possible '_' prefix
|
||||||
unsigned charI = 0;
|
unsigned nChar = 0;
|
||||||
if (hexdigits[0] == '_')
|
if (hexdigits[0] == '_')
|
||||||
{
|
{
|
||||||
++charI;
|
++nChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
// incorrect length - can never match
|
// Incorrect length - can never match
|
||||||
if (hexdigits.size() != charI + length*2)
|
if (hexdigits.size() != nChar + 2*dig_.size())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; ++i)
|
for (const auto& byteVal : dig_)
|
||||||
{
|
{
|
||||||
const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
|
const char upp = hexChars[((byteVal >> 4) & 0xF)]; // Upper nibble
|
||||||
const char c2 = hexChars[(v_[i] & 0xF)];
|
const char low = hexChars[(byteVal & 0xF)]; // Lower nibble
|
||||||
|
|
||||||
if (c1 != hexdigits[charI++]) return false;
|
if (upp != hexdigits[nChar++]) return false;
|
||||||
if (c2 != hexdigits[charI++]) return false;
|
if (low != hexdigits[nChar++]) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -206,32 +214,32 @@ bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
|
|||||||
|
|
||||||
bool Foam::SHA1Digest::operator==(const char* hexdigits) const
|
bool Foam::SHA1Digest::operator==(const char* hexdigits) const
|
||||||
{
|
{
|
||||||
// null or empty string is not an error - interpret as '0000..'
|
// Null or empty string is not an error - interpret as '0000..'
|
||||||
if (!hexdigits || !*hexdigits)
|
if (!hexdigits || !*hexdigits)
|
||||||
{
|
{
|
||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip possible '_' prefix
|
// Skip possible '_' prefix
|
||||||
unsigned charI = 0;
|
unsigned nChar = 0;
|
||||||
if (hexdigits[0] == '_')
|
if (hexdigits[0] == '_')
|
||||||
{
|
{
|
||||||
++charI;
|
++nChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
// incorrect length - can never match
|
// Incorrect length - can never match
|
||||||
if (strlen(hexdigits) != charI + length*2)
|
if (strlen(hexdigits) != nChar + 2*dig_.size())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; ++i)
|
for (const auto& byteVal : dig_)
|
||||||
{
|
{
|
||||||
const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
|
const char upp = hexChars[((byteVal >> 4) & 0xF)];
|
||||||
const char c2 = hexChars[(v_[i] & 0xF)];
|
const char low = hexChars[(byteVal & 0xF)];
|
||||||
|
|
||||||
if (c1 != hexdigits[charI++]) return false;
|
if (upp != hexdigits[nChar++]) return false;
|
||||||
if (c2 != hexdigits[charI++]) return false;
|
if (low != hexdigits[nChar++]) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -256,22 +264,11 @@ bool Foam::SHA1Digest::operator!=(const char* rhs) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::Istream& Foam::operator>>(Istream& is, SHA1Digest& dig)
|
Foam::Istream& Foam::operator>>(Istream& is, SHA1Digest& dig)
|
||||||
{
|
{
|
||||||
unsigned char *v = dig.v_;
|
return dig.read(is);
|
||||||
|
|
||||||
for (unsigned i = 0; i < dig.length; ++i)
|
|
||||||
{
|
|
||||||
unsigned char c1 = SHA1Digest::readHexDigit(is);
|
|
||||||
unsigned char c2 = SHA1Digest::readHexDigit(is);
|
|
||||||
|
|
||||||
v[i] = (c1 << 4) + c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
is.check(FUNCTION_NAME);
|
|
||||||
return is;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
@ -40,6 +40,7 @@ SourceFiles
|
|||||||
#ifndef SHA1Digest_H
|
#ifndef SHA1Digest_H
|
||||||
#define SHA1Digest_H
|
#define SHA1Digest_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -47,30 +48,39 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declaration of classes
|
// Forward Declarations
|
||||||
|
class SHA1;
|
||||||
class Istream;
|
class Istream;
|
||||||
class Ostream;
|
class Ostream;
|
||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
|
||||||
class SHA1;
|
|
||||||
class SHA1Digest;
|
|
||||||
Ostream& operator<<(Ostream&, const SHA1Digest&);
|
|
||||||
Istream& operator>>(Istream&, SHA1Digest&);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class SHA1Digest Declaration
|
Class SHA1Digest Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SHA1Digest
|
class SHA1Digest
|
||||||
{
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- The digest contents, which has 20 (uncoded) bytes
|
||||||
|
std::array<unsigned char, 20> dig_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Pointer to the underlying digest data
|
||||||
|
unsigned char* data()
|
||||||
|
{
|
||||||
|
return dig_.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permit SHA1 to calculate the digest
|
||||||
|
friend class SHA1;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend class SHA1;
|
|
||||||
|
|
||||||
// Static data members
|
|
||||||
|
|
||||||
//- The length of the (uncoded) digest contents
|
// Static Data Members
|
||||||
static const unsigned length = 20;
|
|
||||||
|
|
||||||
//- A null digest (ie, all zero)
|
//- A null digest (ie, all zero)
|
||||||
static const SHA1Digest null;
|
static const SHA1Digest null;
|
||||||
@ -81,8 +91,8 @@ public:
|
|||||||
//- Construct a zero digest
|
//- Construct a zero digest
|
||||||
SHA1Digest();
|
SHA1Digest();
|
||||||
|
|
||||||
//- Construct read a digest
|
//- Read construct a digest
|
||||||
SHA1Digest(Istream&);
|
explicit SHA1Digest(Istream& is);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
@ -96,8 +106,14 @@ public:
|
|||||||
//- Return (40-byte) text representation, optionally with '_' prefix
|
//- Return (40-byte) text representation, optionally with '_' prefix
|
||||||
std::string str(const bool prefixed=false) const;
|
std::string str(const bool prefixed=false) const;
|
||||||
|
|
||||||
|
//- Read (40-byte) text representation.
|
||||||
|
// Since leading and intermediate underscores are skipped, a '_' can
|
||||||
|
// be prefixed to the text representation to use an unquoted
|
||||||
|
// SHA1Digest without parsing ambiguities as a number.
|
||||||
|
Istream& read(Istream& is);
|
||||||
|
|
||||||
//- Write (40-byte) text representation, optionally with '_' prefix
|
//- Write (40-byte) text representation, optionally with '_' prefix
|
||||||
Ostream& write(Ostream&, const bool prefixed=false) const;
|
Ostream& write(Ostream& os, const bool prefixed=false) const;
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -126,33 +142,18 @@ public:
|
|||||||
|
|
||||||
//- Inequality operator
|
//- Inequality operator
|
||||||
bool operator!=(const char* hexdigits) const;
|
bool operator!=(const char* hexdigits) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
|
||||||
|
|
||||||
//- Read (40-byte) text representation
|
|
||||||
// Since leading and intermediate underscores are skipped, a '_' can
|
|
||||||
// be prefixed to the text representation to use an unquoted
|
|
||||||
// SHA1Digest without parsing ambiguities as a number.
|
|
||||||
friend Istream& operator>>(Istream&, SHA1Digest&);
|
|
||||||
|
|
||||||
//- Write (40-byte) text representation, unquoted and without prefix
|
|
||||||
friend Ostream& operator<<(Ostream&, const SHA1Digest&);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- The digest contents
|
|
||||||
unsigned char v_[length];
|
|
||||||
|
|
||||||
//- Read hexadecimal value, ignoring leading or intermediate '_'
|
|
||||||
static unsigned char readHexDigit(Istream&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// IOstream Operators
|
||||||
|
|
||||||
|
//- Read (40-byte) text representation (ignoring leading '_' prefix)
|
||||||
|
Istream& operator>>(Istream&is , SHA1Digest& dig);
|
||||||
|
|
||||||
|
//- Write (40-byte) text representation, unquoted and without prefix
|
||||||
|
Ostream& operator<<(Ostream& os, const SHA1Digest& dig);
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2009-2011, 2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011 OpenFOAM Foundation
|
| Copyright (C) 2011 OpenFOAM Foundation
|
||||||
@ -36,14 +36,14 @@ inline Foam::SHA1::SHA1()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::SHA1::SHA1(const std::string& str)
|
inline Foam::SHA1::SHA1(const char* str)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
append(str);
|
append(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::SHA1::SHA1(const char* str)
|
inline Foam::SHA1::SHA1(const std::string& str)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
append(str);
|
append(str);
|
||||||
@ -59,16 +59,9 @@ inline Foam::SHA1& Foam::SHA1::append(const char* data, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::SHA1& Foam::SHA1::append(const std::string& str)
|
|
||||||
{
|
|
||||||
processBytes(str.data(), str.size());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Foam::SHA1& Foam::SHA1::append(const char* str)
|
inline Foam::SHA1& Foam::SHA1::append(const char* str)
|
||||||
{
|
{
|
||||||
if (str)
|
if (str && *str)
|
||||||
{
|
{
|
||||||
processBytes(str, strlen(str));
|
processBytes(str, strlen(str));
|
||||||
}
|
}
|
||||||
@ -76,17 +69,85 @@ inline Foam::SHA1& Foam::SHA1::append(const char* str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::SHA1& Foam::SHA1::append(const std::string& str)
|
||||||
|
{
|
||||||
|
processBytes(str.data(), str.size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::SHA1& Foam::SHA1::append
|
||||||
|
(
|
||||||
|
const std::string& str,
|
||||||
|
size_t pos,
|
||||||
|
size_t len
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (std::string::npos != pos && pos < str.length())
|
||||||
|
{
|
||||||
|
if (std::string::npos == len || pos + len > str.length())
|
||||||
|
{
|
||||||
|
len = str.length() - pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
processBytes(str.data() + pos, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::SHA1Digest Foam::SHA1::digest() const
|
||||||
|
{
|
||||||
|
SHA1Digest dig;
|
||||||
|
|
||||||
|
if (finalized_)
|
||||||
|
{
|
||||||
|
calcDigest(dig);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Avoid disturbing current data - use a copy
|
||||||
|
SHA1 sha(*this);
|
||||||
|
if (sha.finalize())
|
||||||
|
{
|
||||||
|
sha.calcDigest(dig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string Foam::SHA1::str(const bool prefixed) const
|
||||||
|
{
|
||||||
|
return digest().str(prefixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::Ostream& Foam::SHA1::write(Ostream& os, const bool prefixed) const
|
||||||
|
{
|
||||||
|
return digest().write(os, prefixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline Foam::SHA1::operator Foam::SHA1Digest() const
|
||||||
|
{
|
||||||
|
return digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Foam::SHA1::operator==(const SHA1& rhs) const
|
inline bool Foam::SHA1::operator==(const SHA1& rhs) const
|
||||||
{
|
{
|
||||||
return this->digest() == rhs.digest();
|
return this->digest() == rhs.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Foam::SHA1::operator==(const SHA1Digest& rhs) const
|
inline bool Foam::SHA1::operator==(const SHA1Digest& dig) const
|
||||||
{
|
{
|
||||||
return this->digest() == rhs;
|
return this->digest() == dig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -126,17 +187,11 @@ inline bool Foam::SHA1::operator!=(const char* rhs) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::SHA1::operator Foam::SHA1Digest() const
|
|
||||||
{
|
|
||||||
return digest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
|
||||||
|
|
||||||
inline Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1& sha)
|
inline Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1& sha)
|
||||||
{
|
{
|
||||||
return (os << sha.digest());
|
return sha.write(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user