mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: allow '_' prefix when reading/writing SHA1Digest
- the resulting SHA1 can be written and parsed directly without any ambiguities when it starts with a digit eg, SHA1: _024ea2fa570968069f52f55aa47ee82ac417f5f6 - provide same optional prefix functionality in conversion to string and in comparison with strings - add SHA1Digest::null
This commit is contained in:
@ -151,7 +151,7 @@ void Foam::SHA1::processBytes(const void *data, size_t len)
|
||||
// while (len > 64)
|
||||
while (len >= 64)
|
||||
{
|
||||
processBlock(memcpy (buffer_, data, 64), 64);
|
||||
processBlock(memcpy(buffer_, data, 64), 64);
|
||||
data = reinterpret_cast<const unsigned char*>(data) + 64;
|
||||
len -= 64;
|
||||
}
|
||||
@ -177,7 +177,7 @@ void Foam::SHA1::processBytes(const void *data, size_t len)
|
||||
{
|
||||
processBlock(buffer_, 64);
|
||||
remaining -= 64;
|
||||
memcpy (buffer_, &buffer_[16], remaining);
|
||||
memcpy(buffer_, &buffer_[16], remaining);
|
||||
}
|
||||
bufLen_ = remaining;
|
||||
}
|
||||
@ -241,10 +241,10 @@ Foam::SHA1::processBlock(const void *data, size_t len)
|
||||
while (words < endp)
|
||||
{
|
||||
uint32_t tm;
|
||||
for (int t = 0; t < 16; t++)
|
||||
for (int t = 0; t < 16; ++t)
|
||||
{
|
||||
x[t] = swapBytes (*words);
|
||||
words++;
|
||||
x[t] = swapBytes(*words);
|
||||
++words;
|
||||
}
|
||||
|
||||
R( a, b, c, d, e, F1, K1, x[ 0] );
|
||||
@ -343,11 +343,11 @@ void Foam::SHA1::calcDigest(SHA1Digest& dig) const
|
||||
{
|
||||
unsigned char *r = dig.v_;
|
||||
|
||||
set_uint32 (r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
|
||||
set_uint32 (r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
|
||||
set_uint32 (r + 2 * sizeof(uint32_t), swapBytes(hashsumC_));
|
||||
set_uint32 (r + 3 * sizeof(uint32_t), swapBytes(hashsumD_));
|
||||
set_uint32 (r + 4 * sizeof(uint32_t), swapBytes(hashsumE_));
|
||||
set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
|
||||
set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
|
||||
set_uint32(r + 2 * sizeof(uint32_t), swapBytes(hashsumC_));
|
||||
set_uint32(r + 3 * sizeof(uint32_t), swapBytes(hashsumD_));
|
||||
set_uint32(r + 4 * sizeof(uint32_t), swapBytes(hashsumE_));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -30,6 +30,8 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::SHA1Digest Foam::SHA1Digest::null;
|
||||
|
||||
//! \cond fileScope
|
||||
static const char hexChars[] = "0123456789abcdef";
|
||||
//! \endcond
|
||||
@ -40,12 +42,18 @@ static const char hexChars[] = "0123456789abcdef";
|
||||
unsigned char Foam::SHA1Digest::readHexDigit(Istream& is)
|
||||
{
|
||||
// Takes into account that 'a' (or 'A') is 10
|
||||
static const label alphaOffset = toupper('A') - 10;
|
||||
static const int alphaOffset = toupper('A') - 10;
|
||||
// Takes into account that '0' is 0
|
||||
static const label zeroOffset = int('0');
|
||||
static const int zeroOffset = int('0');
|
||||
|
||||
|
||||
// silently ignore leading or intermediate '_'
|
||||
char c = 0;
|
||||
do
|
||||
{
|
||||
is.read(c);
|
||||
}
|
||||
while (c == '_');
|
||||
|
||||
if (!isxdigit(c))
|
||||
{
|
||||
@ -101,12 +109,21 @@ bool Foam::SHA1Digest::empty() const
|
||||
}
|
||||
|
||||
|
||||
std::string Foam::SHA1Digest::str() const
|
||||
std::string Foam::SHA1Digest::str(const bool prefixed) const
|
||||
{
|
||||
std::string buf;
|
||||
buf.resize(length*2);
|
||||
|
||||
unsigned nChar = 0;
|
||||
|
||||
if (prefixed)
|
||||
{
|
||||
buf.resize(1 + length*2);
|
||||
buf[nChar++] = '_';
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.resize(length*2);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < length; ++i)
|
||||
{
|
||||
buf[nChar++] = hexChars[((v_[i] >> 4) & 0xF)];
|
||||
@ -117,6 +134,24 @@ std::string Foam::SHA1Digest::str() const
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
|
||||
{
|
||||
if (prefixed)
|
||||
{
|
||||
os.write('_');
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < length; ++i)
|
||||
{
|
||||
os.write(hexChars[((v_[i] >> 4) & 0xF)]);
|
||||
os.write(hexChars[(v_[i] & 0xF)]);
|
||||
}
|
||||
|
||||
os.check("SHA1Digest::write(Ostream&, const bool)");
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::SHA1Digest::operator==(const SHA1Digest& rhs) const
|
||||
@ -141,21 +176,26 @@ bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
|
||||
return empty();
|
||||
}
|
||||
|
||||
// skip possible '_' prefix
|
||||
unsigned charI = 0;
|
||||
if (hexdigits[0] == '_')
|
||||
{
|
||||
++charI;
|
||||
}
|
||||
|
||||
// incorrect length - can never match
|
||||
if (hexdigits.size() != length*2)
|
||||
if (hexdigits.size() != charI + length*2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, charI = 0; i < length; ++i, charI += 2)
|
||||
for (unsigned i = 0; i < length; ++i)
|
||||
{
|
||||
const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
|
||||
const char c2 = hexChars[(v_[i] & 0xF)];
|
||||
|
||||
if (c1 != hexdigits[charI] || c2 != hexdigits[charI+1])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (c1 != hexdigits[charI++]) return false;
|
||||
if (c2 != hexdigits[charI++]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -170,21 +210,26 @@ bool Foam::SHA1Digest::operator==(const char* hexdigits) const
|
||||
return empty();
|
||||
}
|
||||
|
||||
// skip possible '_' prefix
|
||||
unsigned charI = 0;
|
||||
if (hexdigits[0] == '_')
|
||||
{
|
||||
++charI;
|
||||
}
|
||||
|
||||
// incorrect length - can never match
|
||||
if (strlen(hexdigits) != length*2)
|
||||
if (strlen(hexdigits) != charI + length*2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, charI = 0; i < length; ++i, charI += 2)
|
||||
for (unsigned i = 0; i < length; ++i)
|
||||
{
|
||||
const char c1 = hexChars[((v_[i] >> 4) & 0xF)];
|
||||
const char c2 = hexChars[(v_[i] & 0xF)];
|
||||
|
||||
if (c1 != hexdigits[charI] || c2 != hexdigits[charI+1])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (c1 != hexdigits[charI++]) return false;
|
||||
if (c2 != hexdigits[charI++]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -230,16 +275,7 @@ Foam::Istream& Foam::operator>>(Istream& is, SHA1Digest& dig)
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const SHA1Digest& dig)
|
||||
{
|
||||
const unsigned char *v = dig.v_;
|
||||
|
||||
for (unsigned i = 0; i < dig.length; ++i)
|
||||
{
|
||||
os.write(hexChars[((v[i] >> 4) & 0xF)]);
|
||||
os.write(hexChars[(v[i] & 0xF)]);
|
||||
}
|
||||
|
||||
os.check("Ostream& operator<<(Ostream&, const SHA1Digest&)");
|
||||
return os;
|
||||
return dig.write(os);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -46,8 +46,8 @@ namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class Ostream;
|
||||
class Istream;
|
||||
class Ostream;
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
class SHA1;
|
||||
@ -65,23 +65,40 @@ class SHA1Digest
|
||||
public:
|
||||
friend class SHA1;
|
||||
|
||||
//- The length of the digest contents
|
||||
// Static data members
|
||||
|
||||
//- The length of the (uncoded) digest contents
|
||||
static const unsigned length = 20;
|
||||
|
||||
//- A null digest (ie, all zero)
|
||||
static const SHA1Digest null;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct a zero digest
|
||||
SHA1Digest();
|
||||
|
||||
//- Construct read a digest
|
||||
SHA1Digest(Istream&);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Reset the digest to zero
|
||||
void clear();
|
||||
|
||||
//- Return true if the digest is empty (ie, all zero).
|
||||
bool empty() const;
|
||||
|
||||
//- Return string representation
|
||||
std::string str() const;
|
||||
//- Return (40-byte) text representation, optionally with '_' prefix
|
||||
std::string str(const bool prefixed=false) const;
|
||||
|
||||
//- Write (40-byte) text representation, optionally with '_' prefix
|
||||
Ostream& write(Ostream&, const bool prefixed=false) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Equality operator
|
||||
bool operator==(const SHA1Digest&) const;
|
||||
@ -89,11 +106,13 @@ public:
|
||||
//- Compare to (40-byte) text representation (eg, from sha1sum)
|
||||
// An %empty string is equivalent to
|
||||
// "0000000000000000000000000000000000000000"
|
||||
// The hexdigits may optionally start with a '_' prefix
|
||||
bool operator==(const std::string& hexdigits) const;
|
||||
|
||||
//- Compare to (40-byte) text representation (eg, from sha1sum)
|
||||
// A %null or %empty string is equivalent to
|
||||
// "0000000000000000000000000000000000000000"
|
||||
// The hexdigits may optionally start with a '_' prefix
|
||||
bool operator==(const char* hexdigits) const;
|
||||
|
||||
|
||||
@ -107,14 +126,27 @@ public:
|
||||
bool operator!=(const char* hexdigits) const;
|
||||
|
||||
|
||||
friend Ostream& operator<<(Ostream&, const SHA1Digest&);
|
||||
|
||||
|
||||
// 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&);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user