Как инвертировать LFSR и сдвинуть регистр в C?
Я программирую систему OFDM, как на стороне передатчика, так и на стороне приемника. Первая функция, куда идут биты - это скремблер, который в основном является LFSR, где мой полином x^7 + x^4 + 1
просто я XOR 7-й и 4-й бит в регистре, и сделать его новым первым битом регистра сдвига, а также XOR это значение с входным значением, чтобы получить выходное значение. Наглядно это видно ниже.
Я работаю с массивом типа short
держать биты. Мне нужен этот тип массива из-за некоторых более поздних функций в программе. Это более удобно для меня. Я создал функцию для сдвига вправо регистра и другую функцию для скремблера. Код можно увидеть ниже:
void leftshift(short *in, short *out, unsigned long len, unsigned short shift) {
unsigned long i;
for (i = 0; i < len - shift; i++) {
out[i] = in[i + shift];
}
for (i = len - shift; i < len; i++) {
out[i] = 0;
}
}
void rightshift(short *in, short *out, unsigned long len, unsigned short shift) {
unsigned long i;
for (i = len - 1; i >= shift; i--) {
out[i] = in[i - 1];
}
for (i = 0; i < shift; i++) {
out[i] = 0;
}
}
void scrambler(short *in, short *out, unsigned long len, short *initial_state) {
unsigned long i;
short carry;
short *shift_register = initial_state;
for (i = 0; i < len; i++) {
carry = (shift_register[3] + shift_register[6]) % 2;
rightshift(shift_register, shift_register, 7, 1);
shift_register[0] = carry;
out[i] = (in[i] + carry) % 2;
}
}
Теперь дело в том, что как часть процесса дескремблера, мне нужно кодировать инверсию скремблера. В моем скремблере я делаю правую смену. Обращает ли это внимание на обратный сдвиг влево, оставляя последовательность касаний и начальную конфигурацию регистра одинаковыми? Хотя, если я делаю сдвиг влево и проверяю результат, он не совпадает с исходным вводом. Есть идеи?
РЕДАКТИРОВАТЬ:
int main(void) {
const unsigned SIZE = 24;
short in[SIZE] = { 0, 0, 0, 0, 1, 0, 0, 0,
0, 1, 1, 1, 0, 0, 1, 0,
1, 0, 0, 1, 1, 1, 0, 0 };
short init[7] = { 1, 1, 1, 1, 1, 1, 1 };
short *out_scrambler = (short *)malloc(sizeof(short)*SIZE);
short *out_descrambler = (short *)malloc(sizeof(short)*SIZE);
scrambler(in, out_scrambler, SIZE, init);
scrambler(out_scrambler, out_descrambler, SIZE, init);
return 0;
}
2 ответа
Процесс скремблирования является его собственным обратным; вам просто нужно снова выполнить XOR с той же последовательностью.
(a ^ b) ^ b == a
У тебя есть A xor X = B
тогда ваш вопрос как получить A
от B
, право? Или я что-то здесь упускаю?
A xor X = B
=> B xor X = A
Кроме того, весь ваш lfsr может быть упрощен до чего-то вроде:
uint8_t state;
outbit = ((state >> 7) ^ (state >> 4)) & 1;
state = (state >> 1) | outbit;
Все дело в том, что они безумно дешевы. Реализация их довольно контрпродуктивно, используя в 128 раз больше памяти и на три или три раза больше инструкций, чем необходимо.