SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
Adler32.cpp
Go to the documentation of this file.
2
3#include <BufferStream.h>
4
5using namespace sourcepp;
6
13namespace tomcrypt {
14
15namespace {
16
17struct adler32_state {
18 uint16_t s[2];
19};
20
21constexpr uint32_t s_adler32_base = 65521;
22
23[[nodiscard]] bool adler32_update(adler32_state& ctx, const uint8_t* input, uint64_t length) {
24 if (!input) {
25 return false;
26 }
27
28 uint64_t s1 = ctx.s[0];
29 uint64_t s2 = ctx.s[1];
30
31 if (length % 8 != 0) {
32 do {
33 s1 += *input++;
34 s2 += s1;
35 length--;
36 } while (length % 8 != 0);
37
38 if (s1 >= s_adler32_base) {
39 s1 -= s_adler32_base;
40 }
41 s2 %= s_adler32_base;
42 }
43
44 while (length > 0) {
45 s1 += input[0];
46 s2 += s1;
47 s1 += input[1];
48 s2 += s1;
49 s1 += input[2];
50 s2 += s1;
51 s1 += input[3];
52 s2 += s1;
53 s1 += input[4];
54 s2 += s1;
55 s1 += input[5];
56 s2 += s1;
57 s1 += input[6];
58 s2 += s1;
59 s1 += input[7];
60 s2 += s1;
61
62 length -= 8;
63 input += 8;
64
65 if (s1 >= s_adler32_base) {
66 s1 -= s_adler32_base;
67 }
68 s2 %= s_adler32_base;
69 }
70
71 if (s1 >= s_adler32_base || s2 >= s_adler32_base) {
72 return false;
73 }
74
75 ctx.s[0] = static_cast<uint16_t>(s1);
76 ctx.s[1] = static_cast<uint16_t>(s2);
77 return true;
78}
79
80[[nodiscard]] uint32_t adler32_finish(const adler32_state& ctx) {
81 return (static_cast<uint32_t>(ctx.s[1]) << 16) | (static_cast<uint32_t>(ctx.s[0]) << 0);
82}
83
84} // namespace
85
86} // namespace tomcrypt
87
88uint32_t crypto::computeAdler32(std::span<const std::byte> buffer) {
89 if (buffer.empty()) {
90 return 0;
91 }
92
93 // NOTE: tomcrypt adler32 initializes state to (1, 0). GCF needs (0, 0) so we are skipping the standard init
94 tomcrypt::adler32_state adler32{};
95 if (!tomcrypt::adler32_update(adler32, reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size())) {
96 return 0;
97 }
98 return tomcrypt::adler32_finish(adler32);
99}
uint32_t computeAdler32(std::span< const std::byte > buffer)
Definition Adler32.cpp:88
Adler-32 checksum algorithm Written and placed in the public domain by Wei Dai Adapted for libtomcryp...
Definition Adler32.cpp:13