31 constexpr auto kiB = (1UL << 10);
33 constexpr auto MiB = (1UL << 20);
35 constexpr auto GiB = (1UL << 30);
37 constexpr auto TiB = (1ULL << 40);
39 constexpr auto PiB = (1ULL << 50);
41 constexpr auto EiB = (1ULL << 60);
43 static auto PrintHex(std::vector<uint8_t>::const_iterator&& begin, std::vector<uint8_t>::const_iterator&& end) ->
void
47 constexpr auto asciiZero = 0x30;
48 constexpr auto asciiA = 0x61 - 0x0a;
50 constexpr auto wordSize = 4;
51 constexpr auto wordCount = 4;
53 char eol_ascii[wordSize * wordCount + 1] = {};
55 std::stringstream prnt;
56 auto size = std::distance(begin, end);
62 aV = (a <= 9 ? asciiZero : asciiA) + a;
63 bV = (b <= 9 ? asciiZero : asciiA) + b;
64 prnt << bV << aV <<
" ";
66 auto col = c % (wordSize * wordCount);
67 eol_ascii[col] = v >= 32 && v <= 127 ? (char)v :
'.';
68 if (col == 0 && c != size)
70 prnt <<
" " << eol_ascii << std::endl;
72 else if (c % wordSize == 0)
80 eol_ascii[col + 1] = 0;
82 prnt << (col != 0 ?
" " :
"") << eol_ascii;
85 std::advance(begin, 1);
88 std::cerr << prnt.str() << std::endl;
91 static constexpr auto _bcd(
const uint8_t& c)
93 return (c & 0x0f) + ((c >> 4) * 10);
96 static constexpr auto _dcb(
const uint8_t& c)
98 return ((
int)(c / 10) * 16) + (c % 10);
101 static auto ParseBCDTimestamp(
const uint8_t time[7]) -> time_t
104 t.tm_year = ((_bcd(time[0]) * 100) + _bcd(time[1])) - 1900;
105 t.tm_mon = _bcd(time[2]) - 1;
106 t.tm_mday = _bcd(time[3]);
107 t.tm_hour = _bcd(time[4]);
108 t.tm_min = _bcd(time[5]);
109 t.tm_sec = _bcd(time[6]);
114 static auto MakeBCDTimestamp(
const struct std::tm& timeinfo) -> std::vector<uint8_t>
117 static_cast<uint8_t
>(_dcb((1900 + timeinfo.tm_year) / 100)),
118 static_cast<uint8_t
>(_dcb(timeinfo.tm_year + 1900 - (timeinfo.tm_year + 1900) / 100 * 100)),
119 static_cast<uint8_t
>(_dcb(timeinfo.tm_mon + 1)),
120 static_cast<uint8_t
>(_dcb(timeinfo.tm_mday)),
121 static_cast<uint8_t
>(_dcb(timeinfo.tm_hour)),
122 static_cast<uint8_t
>(_dcb(timeinfo.tm_min)),
123 static_cast<uint8_t
>(_dcb(timeinfo.tm_sec)),
127 static inline auto ApplyXOR(std::vector<uint8_t>& data,
const uint8_t* xor_key,
const uint16_t& key_len,
const uint16_t& xor_offset = 0) ->
void
129 for (
size_t z = 0; z < data.size(); z++)
131 data[z] = data[z] ^ xor_key[(xor_offset + z) % key_len];
135 static inline auto ApplyXOR(std::vector<uint8_t>::iterator&& begin, std::vector<uint8_t>::iterator&& end,
const uint8_t* xor_key,
const uint16_t& key_len,
const uint16_t& xor_offset = 0) ->
void
140 (*begin) = (*begin) ^ xor_key[(xor_offset + z++) % key_len];
141 std::advance(begin, 1);
145 static auto BSDChecksum(std::vector<uint8_t>::iterator& data,
const uint32_t& size) -> uint16_t
147 int32_t checksum = 0u;
149 for (
size_t i = 0; i < size; i++)
151 checksum = (checksum >> 1) + ((checksum & 1) << 15);
154 std::advance(data, 1);
159 static auto Fletcher16(std::vector<uint8_t>::iterator& data,
const uint32_t& size) -> uint16_t
161 constexpr auto block_size = 5802;
162 uint32_t c0 = 0, c1 = 0;
168 for (c0 = c1 = 0; len > 0; len -= block_size)
170 uint32_t blocklen = std::min(block_size, len);
171 for (i = 0; i < blocklen; ++i)
175 std::advance(data, 1);
183 return (c1 << 8 | c0);
186 static auto InternetChecksum(std::vector<uint8_t>::iterator& data,
const uint32_t& size) -> uint16_t
196 std::advance(data, 1);
208 sum = (sum & 0xFFFF) + (sum >> 16);
217 static auto CSChecksum(std::vector<uint8_t>::const_iterator&& begin,
const std::vector<uint8_t>::const_iterator&& end) -> uint16_t
224 std::advance(begin, 1);
227 auto c0 = (int32_t)(sum / 5) >> 8;
228 auto c1 = (sum / 5) & 0xff;
229 return (c1 << 8 | c0);
232 static auto FormatBytes(
const uint64_t& bytes,
const uint8_t& precision = 2) -> std::string
234 std::stringstream ss;
235 ss << std::fixed << std::setprecision(precision);
238 ss << (bytes / (double)EiB) <<
" EiB";
240 else if (bytes >= PiB)
242 ss << (bytes / (double)PiB) <<
" PiB";
244 else if (bytes >= TiB)
246 ss << (bytes / (double)TiB) <<
" TiB";
248 else if (bytes >= GiB)
250 ss << (bytes / (double)GiB) <<
" GiB";
252 else if (bytes >= kiB)
254 ss << (bytes / (double)kiB) <<
" kiB";