SHA1Digest.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2015 OpenFOAM Foundation
9  Copyright (C) 2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "SHA1Digest.H"
30 #include "IOstreams.H"
31 #include <cstring>
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
36 
37 static const char hexChars[] = "0123456789abcdef";
38 
39 // The char '0' == 0
40 static constexpr int offsetZero = int('0');
41 
42 // The char 'A' (or 'a') == 10
43 static constexpr int offsetUpper = int('A') - 10;
44 
45 
46 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
47 
48 namespace Foam
49 {
50 
51 // Read hexadecimal value, ignoring leading or intermediate '_'
52 static unsigned char readHexDigit(Istream& is)
53 {
54  // Silently ignore leading or intermediate '_'
55  char c = 0;
56  do
57  {
58  is.read(c);
59  }
60  while (c == '_');
61 
62  if (isdigit(c))
63  {
64  return int(c) - offsetZero;
65  }
66  else if (!isxdigit(c))
67  {
69  << "Illegal hex digit: '" << c << "'"
70  << exit(FatalIOError);
71  }
72 
73  return toupper(c) - offsetUpper;
74 }
75 
76 } // End namespace Foam
77 
78 
79 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
80 
82 {
83  clear();
84 }
85 
86 
88 {
89  clear();
90  read(is);
91 }
92 
93 
94 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
95 
97 {
98  dig_.fill(0); // Same as memset(dig_.data(), 0, dig_.size());
99 }
100 
101 
103 {
104  for (const auto& byteVal : dig_)
105  {
106  if (byteVal)
107  {
108  return false;
109  }
110  }
111 
112  return true;
113 }
114 
115 
116 std::string Foam::SHA1Digest::str(const bool prefixed) const
117 {
118  std::string buf;
119  unsigned nChar = 0;
120 
121  if (prefixed)
122  {
123  buf.resize(1 + 2*dig_.size());
124  buf[nChar++] = '_';
125  }
126  else
127  {
128  buf.resize(2*dig_.size());
129  }
130 
131  for (const auto& byteVal : dig_)
132  {
133  buf[nChar++] = hexChars[((byteVal >> 4) & 0xF)]; // Upper nibble
134  buf[nChar++] = hexChars[(byteVal & 0xF)]; // Lower nibble
135  }
136 
137  return buf;
138 }
139 
140 
142 {
143  for (auto& byteVal : dig_)
144  {
145  const unsigned char upp = readHexDigit(is);
146  const unsigned char low = readHexDigit(is);
147 
148  byteVal = (upp << 4) + low;
149  }
150 
151  is.check(FUNCTION_NAME);
152  return is;
153 }
154 
155 
156 Foam::Ostream& Foam::SHA1Digest::write(Ostream& os, const bool prefixed) const
157 {
158  if (prefixed)
159  {
160  os.write('_');
161  }
162 
163  for (const auto& byteVal : dig_)
164  {
165  os.write(hexChars[((byteVal >> 4) & 0xF)]); // Upper nibble
166  os.write(hexChars[(byteVal & 0xF)]); // Lower nibble
167  }
168 
170  return os;
171 }
172 
173 
174 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
175 
177 {
178  return (dig_ == rhs.dig_);
179 }
180 
181 
182 bool Foam::SHA1Digest::operator==(const std::string& hexdigits) const
183 {
184  // Null or empty string is not an error - interpret as '0000..'
185  if (hexdigits.empty())
186  {
187  return empty();
188  }
189 
190  // Skip possible '_' prefix
191  unsigned nChar = 0;
192  if (hexdigits[0] == '_')
193  {
194  ++nChar;
195  }
196 
197  // Incorrect length - can never match
198  if (hexdigits.size() != nChar + 2*dig_.size())
199  {
200  return false;
201  }
202 
203  for (const auto& byteVal : dig_)
204  {
205  const char upp = hexChars[((byteVal >> 4) & 0xF)]; // Upper nibble
206  const char low = hexChars[(byteVal & 0xF)]; // Lower nibble
207 
208  if (upp != hexdigits[nChar++]) return false;
209  if (low != hexdigits[nChar++]) return false;
210  }
211 
212  return true;
213 }
214 
215 
216 bool Foam::SHA1Digest::operator==(const char* hexdigits) const
217 {
218  // Null or empty string is not an error - interpret as '0000..'
219  if (!hexdigits || !*hexdigits)
220  {
221  return empty();
222  }
223 
224  // Skip possible '_' prefix
225  unsigned nChar = 0;
226  if (hexdigits[0] == '_')
227  {
228  ++nChar;
229  }
230 
231  // Incorrect length - can never match
232  if (strlen(hexdigits) != nChar + 2*dig_.size())
233  {
234  return false;
235  }
236 
237  for (const auto& byteVal : dig_)
238  {
239  const char upp = hexChars[((byteVal >> 4) & 0xF)];
240  const char low = hexChars[(byteVal & 0xF)];
241 
242  if (upp != hexdigits[nChar++]) return false;
243  if (low != hexdigits[nChar++]) return false;
244  }
245 
246  return true;
247 }
248 
249 
251 {
252  return !operator==(rhs);
253 }
254 
255 
256 bool Foam::SHA1Digest::operator!=(const std::string& rhs) const
257 {
258  return !operator==(rhs);
259 }
260 
261 
262 bool Foam::SHA1Digest::operator!=(const char* rhs) const
263 {
264  return !operator==(rhs);
265 }
266 
267 
268 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
269 
271 {
272  return dig.read(is);
273 }
274 
275 
277 {
278  return dig.write(os);
279 }
280 
281 
282 // ************************************************************************* //
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::SHA1Digest::SHA1Digest
SHA1Digest()
Construct a zero digest.
Definition: SHA1Digest.C:81
Foam::SHA1Digest::operator==
bool operator==(const SHA1Digest &) const
Equality operator.
Definition: SHA1Digest.C:176
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::SHA1Digest::clear
void clear()
Reset the digest to zero.
Definition: SHA1Digest.C:96
Foam::FatalIOError
IOerror FatalIOError
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:230
hexChars
static const char hexChars[]
Definition: SHA1Digest.C:37
Foam::SHA1Digest::null
static const SHA1Digest null
A null digest (ie, all zero)
Definition: SHA1Digest.H:86
Foam::OBJstream::write
virtual Ostream & write(const char c)
Write character.
Definition: OBJstream.C:78
Foam::SHA1Digest::empty
bool empty() const
Return true if the digest is empty (ie, all zero).
Definition: SHA1Digest.C:102
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
SHA1Digest.H
Foam::SHA1Digest::write
Ostream & write(Ostream &os, const bool prefixed=false) const
Write (40-byte) text representation, optionally with '_' prefix.
Definition: SHA1Digest.C:156
Foam::operator==
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
offsetZero
static constexpr int offsetZero
Definition: SHA1Digest.C:40
Foam::readHexDigit
static unsigned char readHexDigit(Istream &is)
Definition: SHA1Digest.C:52
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
offsetUpper
static constexpr int offsetUpper
Definition: SHA1Digest.C:43
os
OBJstream os(runTime.globalPath()/outputName)
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::SHA1Digest
The SHA1 message digest.
Definition: SHA1Digest.H:60
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
clear
patchWriters clear()
Foam::SHA1Digest::operator!=
bool operator!=(const SHA1Digest &) const
Inequality operator.
Definition: SHA1Digest.C:250
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::SHA1Digest::read
Istream & read(Istream &is)
Read (40-byte) text representation.
Definition: SHA1Digest.C:141
Foam::SHA1Digest::str
std::string str(const bool prefixed=false) const
Return (40-byte) text representation, optionally with '_' prefix.
Definition: SHA1Digest.C:116
Foam::Istream::read
virtual Istream & read(token &)=0
Return next token from stream.