如何在 C 中反转 LFSR 和移位寄存器?
How to inverse LFSR and shift register in C?
我正在编写一个 OFDM 系统,包括发射器和接收器端。比特进入的第一个函数是扰频器,它基本上是一个 LFSR,我的多项式是 x^7 + x^4 + 1
,简单地说,我对寄存器中的第 7 位和第 4 位进行异或,并将其作为新的移位的第一位寄存器,并将该值与输入值异或,以获得输出值。如图所示,如下图。
我正在使用一个 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;
}
加扰过程是它自己的逆过程;你只需要再次与相同的序列进行异或。
(a ^ b) ^ b == a
你有A xor X = B
,你的问题是如何从B
得到A
,对吧?或者我在这里遗漏了什么?
A xor X = B
=> B xor X = A
此外,您的整个 lfsr 可以简化为:
uint8_t state;
outbit = ((state >> 7) ^ (state >> 4)) & 1;
state = (state >> 1) | outbit;
lfsrs 的全部意义在于它们非常便宜。使用比必要多 128 倍的内存和一个或三个以上的指令来实现它们会适得其反。
我正在编写一个 OFDM 系统,包括发射器和接收器端。比特进入的第一个函数是扰频器,它基本上是一个 LFSR,我的多项式是 x^7 + x^4 + 1
,简单地说,我对寄存器中的第 7 位和第 4 位进行异或,并将其作为新的移位的第一位寄存器,并将该值与输入值异或,以获得输出值。如图所示,如下图。
我正在使用一个 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;
}
加扰过程是它自己的逆过程;你只需要再次与相同的序列进行异或。
(a ^ b) ^ b == a
你有A xor X = B
,你的问题是如何从B
得到A
,对吧?或者我在这里遗漏了什么?
A xor X = B
=> B xor X = A
此外,您的整个 lfsr 可以简化为:
uint8_t state;
outbit = ((state >> 7) ^ (state >> 4)) & 1;
state = (state >> 1) | outbit;
lfsrs 的全部意义在于它们非常便宜。使用比必要多 128 倍的内存和一个或三个以上的指令来实现它们会适得其反。