11 #include <machine/endian.h>
12#elif !defined(_MSC_VER)
31 m_hash[0] = 0x67452301;
32 m_hash[1] = 0xefcdab89;
33 m_hash[2] = 0x98badcfe;
34 m_hash[3] = 0x10325476;
35 m_hash[4] = 0xc3d2e1f0;
42 inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d)
44 return d ^ (b & (c ^ d));
47 inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d)
52 inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d)
54 return (b & c) | (b & d) | (c & d);
57 inline uint32_t rotate(uint32_t a, uint32_t c)
59 return (a << c) | (a >> (32 - c));
62 inline uint32_t swap(uint32_t x)
64#if defined(__GNUC__) || defined(__clang__)
65 return __builtin_bswap32(x);
68 return _byteswap_ulong(x);
72 ((x >> 8) & 0x0000FF00) |
73 ((x << 8) & 0x00FF0000) |
80void SHA1::processBlock(
const void* data)
83 uint32_t a = m_hash[0];
84 uint32_t b = m_hash[1];
85 uint32_t c = m_hash[2];
86 uint32_t d = m_hash[3];
87 uint32_t e = m_hash[4];
90 const uint32_t* input = (uint32_t*) data;
93 for (
int i = 0; i < 16; i++)
94#
if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN)
97 words[i] = swap(input[i]);
101 for (
int i = 16; i < 80; i++)
102 words[i] = rotate(words[i-3] ^ words[i-8] ^ words[i-14] ^ words[i-16], 1);
105 for (
int i = 0; i < 4; i++)
108 e += rotate(a,5) + f1(b,c,d) + words[offset ] + 0x5a827999; b = rotate(b,30);
109 d += rotate(e,5) + f1(a,b,c) + words[offset+1] + 0x5a827999; a = rotate(a,30);
110 c += rotate(d,5) + f1(e,a,b) + words[offset+2] + 0x5a827999; e = rotate(e,30);
111 b += rotate(c,5) + f1(d,e,a) + words[offset+3] + 0x5a827999; d = rotate(d,30);
112 a += rotate(b,5) + f1(c,d,e) + words[offset+4] + 0x5a827999; c = rotate(c,30);
116 for (
int i = 4; i < 8; i++)
119 e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0x6ed9eba1; b = rotate(b,30);
120 d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0x6ed9eba1; a = rotate(a,30);
121 c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0x6ed9eba1; e = rotate(e,30);
122 b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0x6ed9eba1; d = rotate(d,30);
123 a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0x6ed9eba1; c = rotate(c,30);
127 for (
int i = 8; i < 12; i++)
130 e += rotate(a,5) + f3(b,c,d) + words[offset ] + 0x8f1bbcdc; b = rotate(b,30);
131 d += rotate(e,5) + f3(a,b,c) + words[offset+1] + 0x8f1bbcdc; a = rotate(a,30);
132 c += rotate(d,5) + f3(e,a,b) + words[offset+2] + 0x8f1bbcdc; e = rotate(e,30);
133 b += rotate(c,5) + f3(d,e,a) + words[offset+3] + 0x8f1bbcdc; d = rotate(d,30);
134 a += rotate(b,5) + f3(c,d,e) + words[offset+4] + 0x8f1bbcdc; c = rotate(c,30);
138 for (
int i = 12; i < 16; i++)
141 e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0xca62c1d6; b = rotate(b,30);
142 d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0xca62c1d6; a = rotate(a,30);
143 c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0xca62c1d6; e = rotate(e,30);
144 b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0xca62c1d6; d = rotate(d,30);
145 a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0xca62c1d6; c = rotate(c,30);
160 const uint8_t* current = (
const uint8_t*) data;
162 if (m_bufferSize > 0)
164 while (numBytes > 0 && m_bufferSize < BlockSize)
166 m_buffer[m_bufferSize++] = *current++;
172 if (m_bufferSize == BlockSize)
174 processBlock((
void*)m_buffer);
175 m_numBytes += BlockSize;
184 while (numBytes >= BlockSize)
186 processBlock(current);
187 current += BlockSize;
188 m_numBytes += BlockSize;
189 numBytes -= BlockSize;
195 m_buffer[m_bufferSize++] = *current++;
202void SHA1::processBuffer()
211 size_t paddedLength = m_bufferSize * 8;
217 size_t lower11Bits = paddedLength & 511;
218 if (lower11Bits <= 448)
219 paddedLength += 448 - lower11Bits;
221 paddedLength += 512 + 448 - lower11Bits;
226 unsigned char extra[BlockSize];
229 if (m_bufferSize < BlockSize)
230 m_buffer[m_bufferSize] = 128;
235 for (i = m_bufferSize + 1; i < BlockSize; i++)
237 for (; i < paddedLength; i++)
238 extra[i - BlockSize] = 0;
241 uint64_t msgBits = 8 * (m_numBytes + m_bufferSize);
243 unsigned char* addLength;
244 if (paddedLength < BlockSize)
245 addLength = m_buffer + paddedLength;
247 addLength = extra + paddedLength - BlockSize;
250 *addLength++ = (
unsigned char)((msgBits >> 56) & 0xFF);
251 *addLength++ = (
unsigned char)((msgBits >> 48) & 0xFF);
252 *addLength++ = (
unsigned char)((msgBits >> 40) & 0xFF);
253 *addLength++ = (
unsigned char)((msgBits >> 32) & 0xFF);
254 *addLength++ = (
unsigned char)((msgBits >> 24) & 0xFF);
255 *addLength++ = (
unsigned char)((msgBits >> 16) & 0xFF);
256 *addLength++ = (
unsigned char)((msgBits >> 8) & 0xFF);
257 *addLength = (
unsigned char)( msgBits & 0xFF);
260 processBlock(m_buffer);
262 if (paddedLength > BlockSize)
271 unsigned char rawHash[HashBytes];
276 result.reserve(2 * HashBytes);
277 for (
int i = 0; i < HashBytes; i++)
279 static const char dec2hex[16+1] =
"0123456789abcdef";
280 result += dec2hex[(rawHash[i] >> 4) & 15];
281 result += dec2hex[ rawHash[i] & 15];
292 uint32_t oldHash[HashValues];
293 for (
int i = 0; i < HashValues; i++)
294 oldHash[i] = m_hash[i];
299 unsigned char* current = buffer;
300 for (
int i = 0; i < HashValues; i++)
302 *current++ = (m_hash[i] >> 24) & 0xFF;
303 *current++ = (m_hash[i] >> 16) & 0xFF;
304 *current++ = (m_hash[i] >> 8) & 0xFF;
305 *current++ = m_hash[i] & 0xFF;
308 m_hash[i] = oldHash[i];
326 add(text.c_str(), text.size());
void add(const void *data, size_t numBytes)
add arbitrary number of bytes
std::string operator()(const void *data, size_t numBytes)
compute SHA1 of a memory block
std::string getHash()
return latest hash as 40 hex characters