Как инвертировать 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 раз больше памяти и на три или три раза больше инструкций, чем необходимо.

Другие вопросы по тегам