97 lines
3.2 KiB
C++

#ifndef SCRAMBLER_H
#define SCRAMBLER_H
#include <array>
#include <cstdint>
#include <stdexcept>
#include <vector>
/**
* @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<uint8_t> scrambleSyncPreamble(const std::vector<uint8_t>& preamble) const {
static const std::array<uint8_t, 32> 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<uint8_t> 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<uint8_t> scrambleData(const std::vector<uint8_t>& data) {
std::vector<uint8_t> 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