lacteApp
C++17 service for Lacte hardware
Loading...
Searching...
No Matches
fast_crc.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstdint>
5#include <fstream>
6#include <iostream>
7#include <string>
8
15class FastCrc {
16 public:
17 static constexpr uint32_t POLY = 0x4C11DB7;
18 static constexpr size_t DEFAULT_SIZE = 0x08080000 - 0x08008000;
19 static constexpr size_t BIT_IN_BYTE = 8;
20 static constexpr int UINT32_BIT_COUNT = 32;
21 static constexpr int TOP_BYTE_SHIFT = 24;
22 static constexpr uint32_t BYTE_MASK = 0xFF;
23 static auto set_crc32_init_value(const uint32_t start) -> uint32_t {
24 uint32_t init = 0;
25
26 if (start != 0U) {
27 int val = UINT32_BIT_COUNT;
28 while (val != 0) {
29 val -= BIT_IN_BYTE;
30 const uint32_t byte = start >> val & 0xFF;
31 // ReSharper disable once CppRedundantParentheses
32 init = CRC32_TABLE[init >> TOP_BYTE_SHIFT ^ (byte & BYTE_MASK)] ^
33 init << BIT_IN_BYTE;
34 }
35 }
36 return init;
37 }
38
39 static auto fast_crc32(uint32_t sum, const unsigned char* ptr, uint32_t len)
40 -> uint32_t {
41 while (len-- != 0U) {
42 const size_t index = sum >> 24 ^ *ptr++;
43 sum = CRC32_TABLE[index] ^ sum << BIT_IN_BYTE;
44 }
45 return sum;
46 }
47
48 static auto check_app_valid(const std::string_view file_path) -> bool {
49 std::ifstream content{std::string(file_path)};
50 if (!content) {
51 std::cerr << "Failed to open file: " << file_path << '\n';
52 return false;
53 }
54 content.seekg(0, std::ios::end);
55 const size_t size = content.tellg();
56 content.seekg(0, std::ios::beg);
57 if (size < 4) {
58 std::cerr << "File too small to contain CRC: " << file_path << '\n';
59 return false;
60 }
61 auto* const buffer = new char[size];
62 content.read(buffer, static_cast<int>(size));
63 if (!content) {
64 std::cerr << "Failed to read file: " << file_path << '\n';
65 delete[] buffer;
66 return false;
67 }
68 const bool result = check(buffer, size);
69 delete[] buffer;
70 return result;
71 }
72
73 // Первое слово из всех единиц — область flash-памяти ещё не была записана.
74 static constexpr uint32_t ERASED_FLASH_MARKER = 0xFFFFFFFF;
75
76 static auto check(char* base, const uint32_t size = DEFAULT_SIZE) -> bool {
77 if (*reinterpret_cast<uint32_t*>(base) == ERASED_FLASH_MARKER) {
78 return false;
79 }
80 uint32_t csum = set_crc32_init_value(0x00000000);
81 csum = fast_crc32(csum, reinterpret_cast<unsigned char*>(base), size - 4);
82 const uint32_t wrote_crc = *reinterpret_cast<uint32_t*>(base + size - 4);
83
84 return csum == wrote_crc;
85 }
86
87 private:
88 static constexpr std::array<uint32_t, 256> CRC32_TABLE = {
89 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
90 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
91 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
92 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
93 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
94 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
95 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
96 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
97 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
98 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
99 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
100 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
101 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
102 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
103 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
104 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
105 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
106 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
107 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
108 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
109 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
110 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
111 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
112 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
113 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
114 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
115 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
116 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
117 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
118 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
119 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
120 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
121 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
122 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
123 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
124 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
125 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
126 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
127 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
128 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
129 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
130 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
131 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
132};
static constexpr uint32_t BYTE_MASK
Definition fast_crc.hpp:22
static constexpr int TOP_BYTE_SHIFT
Definition fast_crc.hpp:21
static constexpr size_t DEFAULT_SIZE
Definition fast_crc.hpp:18
static auto check_app_valid(const std::string_view file_path) -> bool
Definition fast_crc.hpp:48
static auto check(char *base, const uint32_t size=DEFAULT_SIZE) -> bool
Definition fast_crc.hpp:76
static constexpr int UINT32_BIT_COUNT
Definition fast_crc.hpp:20
static auto fast_crc32(uint32_t sum, const unsigned char *ptr, uint32_t len) -> uint32_t
Definition fast_crc.hpp:39
static constexpr size_t BIT_IN_BYTE
Definition fast_crc.hpp:19
static auto set_crc32_init_value(const uint32_t start) -> uint32_t
Definition fast_crc.hpp:23
static constexpr uint32_t ERASED_FLASH_MARKER
Definition fast_crc.hpp:74
static constexpr uint32_t POLY
Definition fast_crc.hpp:17