diff --git a/src/utils.h b/src/utils.h index 983be61..29db588 100644 --- a/src/utils.h +++ b/src/utils.h @@ -2,6 +2,7 @@ // Created by awalol on 2026/3/4. // +#include #include #include #include @@ -89,18 +90,37 @@ inline const char *opcode_to_str(const uint16_t opcode) { } } -inline uint32_t crc32(const uint8_t* data, size_t size) { - uint32_t crc = ~0xEADA2D49; // 0xA2 seed +inline constexpr uint32_t crc32_table_entry(uint32_t index) { + for (unsigned bit = 0; bit < 8; ++bit) { + index = (index >> 1) ^ (0xEDB88320 & -(index & 1)); + } + return index; +} + +inline constexpr auto make_crc32_table() { + std::array table{}; + for (uint32_t i = 0; i < table.size(); ++i) { + table[i] = crc32_table_entry(i); + } + return table; +} + +inline constexpr auto crc32_lookup_table = make_crc32_table(); + +inline uint32_t crc32_seeded(const uint8_t *data, size_t size, const uint32_t seed) { + uint32_t crc = ~seed; while (size--) { - crc ^= *data++; - for (unsigned i = 0; i < 8; i++) - crc = ((crc >> 1) ^ (0xEDB88320 & -(crc & 1))); + crc = (crc >> 8) ^ crc32_lookup_table[(crc ^ *data++) & 0xff]; } return ~crc; } +inline uint32_t crc32(const uint8_t* data, size_t size) { + return crc32_seeded(data, size, 0xEADA2D49); // 0xA2 seed +} + inline void fill_output_report_checksum(uint8_t* outputData,size_t len) { uint32_t crc = crc32(outputData, len - 4); @@ -112,15 +132,7 @@ inline void fill_output_report_checksum(uint8_t* outputData,size_t len) inline uint32_t crc32_feature(const uint8_t *data, std::size_t size) { // https://github.com/rafaelvaloto/Dualsense-Multiplatform/blob/main/Source/Private/GCore/Utils/CR32.cpp - uint32_t crc = ~0x2060efc3; // 0x53 seed - - while (size--) { - crc ^= *data++; - for (unsigned i = 0; i < 8; i++) - crc = ((crc >> 1) ^ (0xEDB88320 & -(crc & 1))); - } - - return ~crc; + return crc32_seeded(data, size, 0x2060efc3); // 0x53 seed } inline void fill_feature_report_checksum(uint8_t *data, const size_t len) { @@ -242,4 +254,4 @@ inline void print_hex(const uint8_t* data,size_t size) { std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast(data[i]) << " "; } std::cout << std::endl; -} \ No newline at end of file +}