#ifndef SCRAMBLER_H #define SCRAMBLER_H #include #include #include #include /** * @class Scrambler * @brief A class that performs scrambling operations for data sequences. */ class Scrambler { public: /** * @brief Constructor initializes the scrambler with a predefined register value. */ Scrambler() : data_sequence_register(0x0BAD) {} /** * @brief Scrambles a synchronization preamble using a fixed randomizer sequence. * @param preamble The synchronization preamble to scramble. * @return The scrambled synchronization preamble. */ std::vector scrambleSyncPreamble(const std::vector& preamble) const { static const std::array sync_randomizer_sequence = { 7, 4, 3, 0, 5, 1, 5, 0, 2, 2, 1, 1, 5, 7, 4, 3, 5, 0, 2, 6, 2, 1, 6, 2, 0, 0, 5, 0, 5, 2, 6, 6 }; std::vector scrambled_preamble; scrambled_preamble.reserve(preamble.size()); // Preallocate to improve efficiency for (size_t i = 0; i < preamble.size(); ++i) { uint8_t scrambled_value = (preamble[i] + sync_randomizer_sequence[i % sync_randomizer_sequence.size()]) % 8; scrambled_preamble.push_back(scrambled_value); } return scrambled_preamble; } /** * @brief Scrambles data using a pseudo-random sequence generated from an LFSR. * @param data The data to scramble. * @return The scrambled data. */ std::vector scrambleData(const std::vector& data) { std::vector scrambled_data; scrambled_data.reserve(data.size()); // Preallocate to improve efficiency for (size_t i = 0; i < data.size(); ++i) { uint8_t random_value = getNextRandomValue(); uint8_t scrambled_value = (data[i] + random_value) % 8; scrambled_data.push_back(scrambled_value); } return scrambled_data; } private: uint16_t data_sequence_register; /** * @brief Generates the next value from the data sequence randomizing generator. * @return A 3-bit random value (0-7) from the current state of the LFSR. */ uint8_t getNextRandomValue() { uint8_t output = data_sequence_register & 0x07; for (int i = 0; i < 8; ++i) { // Get the most significant bit uint16_t msb = (data_sequence_register >> 11) & 0x01; // XOR taps and shift into the LFSR uint16_t bit1 = (data_sequence_register & 0x01) ^ msb; uint16_t bit4 = ((data_sequence_register >> 3) & 0x01) ^ msb; uint16_t bit6 = ((data_sequence_register >> 5) & 0x01) ^ msb; // Update specific bits in the shift register data_sequence_register = (data_sequence_register & ~(1 << 5)) | (bit6 << 5); data_sequence_register = (data_sequence_register & ~(1 << 3)) | (bit4 << 3); data_sequence_register = (data_sequence_register & ~0x01) | bit1; // Shift left and insert the MSB data_sequence_register = (data_sequence_register << 1) | msb; // Keep the LFSR in 12 bits data_sequence_register &= 0x0FFF; } return output; } }; #endif