29inline std::array<uint8_t, 20>
Sha1(
const uint8_t* data, std::size_t len) {
31 uint32_t h0 = 0x67452301, h1 = 0xEFCDAB89, h2 = 0x98BADCFE, h3 = 0x10325476, h4 = 0xC3D2E1F0;
34 uint64_t bit_len =
static_cast<uint64_t
>(len) * 8;
36 std::size_t padded_len = ((len + 8) / 64 + 1) * 64;
39 uint8_t stack_buf[128];
41 bool heap = padded_len >
sizeof(stack_buf);
43 msg =
new uint8_t[padded_len]();
46 std::memset(msg, 0, padded_len);
48 std::memcpy(msg, data, len);
51 for (
int i = 0; i < 8; ++i) {
52 msg[padded_len - 1 - i] =
static_cast<uint8_t
>(bit_len >> (i * 8));
55 auto left_rotate = [](uint32_t v,
unsigned n) -> uint32_t {
return (v << n) | (v >> (32 - n)); };
57 for (std::size_t offset = 0; offset < padded_len; offset += 64) {
59 for (
int i = 0; i < 16; ++i) {
60 w[i] =
static_cast<uint32_t
>(msg[offset + 4 * i]) << 24 |
static_cast<uint32_t
>(msg[offset + 4 * i + 1]) << 16 |
61 static_cast<uint32_t
>(msg[offset + 4 * i + 2]) << 8 |
static_cast<uint32_t
>(msg[offset + 4 * i + 3]);
63 for (
int i = 16; i < 80; ++i) {
64 w[i] = left_rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
66 uint32_t a = h0, b = h1, c = h2, d = h3, e = h4;
67 for (
int i = 0; i < 80; ++i) {
70 f = (b & c) | ((~b) & d);
76 f = (b & c) | (b & d) | (c & d);
82 uint32_t temp = left_rotate(a, 5) + f + e + k + w[i];
85 c = left_rotate(b, 30);
100 std::array<uint8_t, 20> digest;
101 auto store = [&](
int idx, uint32_t val) {
102 digest[idx * 4 + 0] =
static_cast<uint8_t
>(val >> 24);
103 digest[idx * 4 + 1] =
static_cast<uint8_t
>(val >> 16);
104 digest[idx * 4 + 2] =
static_cast<uint8_t
>(val >> 8);
105 digest[idx * 4 + 3] =
static_cast<uint8_t
>(val);
120 static const char kTable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
122 out.reserve(4 * ((len + 2) / 3));
123 for (std::size_t i = 0; i < len; i += 3) {
124 uint32_t n =
static_cast<uint32_t
>(data[i]) << 16;
125 if (i + 1 < len) n |=
static_cast<uint32_t
>(data[i + 1]) << 8;
126 if (i + 2 < len) n |=
static_cast<uint32_t
>(data[i + 2]);
127 out.push_back(kTable[(n >> 18) & 0x3F]);
128 out.push_back(kTable[(n >> 12) & 0x3F]);
129 out.push_back((i + 1 < len) ? kTable[(n >> 6) & 0x3F] :
'=');
130 out.push_back((i + 2 < len) ? kTable[n & 0x3F] :
'=');