非二进制线性反馈移位寄存器

时间:2012-11-15 22:47:20

标签: python math language-agnostic

我使用Wikipedia上的指令在Python中编写Galois线性反馈移位寄存器:

def lfsr(coefficients, state):
    while 1:
        lsb = state.pop()
        state.insert(0, 0)
        if lsb:
            state = app(coefficients, state)

        yield lsb

def app(coefficients, state):
    return [ (coefficients[i]^state[i]) for i in range(len(state)) ]

L = lfsr([1,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,1], [0]*15+[1])
seq = [ str(L.next()) for i in range(2**16+16) ]

这很好用。我现在要做的是编写一个可以处理除GF(2)以外的Galois字段的通用版本,但我不理解有关non-binary LFSRs的部分。这部分对我没有意义:“反馈位(输出位)乘以q-ary值(模q),每个特定的抽头点都是常数。”如何将单个输出位乘以每个抽头点的值?

这是我提出的,但不是给出循环序列,输出很快恶化到全0:

# Multiplication table for GF(4)
mult_4 = [[0, 0, 0, 0],
          [0, 1, 2, 3],
          [0, 2, 3, 1],
          [0, 3, 1, 2]]

def lfsr(coefficients, state):
    while 1:
        lsb = state.pop()
        state.insert(0, 0)
        state = app(coefficients, state)

        yield lsb

def app(coefficients, state):
    return [ mult_4[coefficients[i]][state[i]] for i in range(len(state)) ]

L = lfsr([ 1, 0, 0, 0, 1, 2, 3 ], [1]*6)
seq = [ str(L.next()) for i in range(4**6+6) ]

2 个答案:

答案 0 :(得分:1)

我建议你熟悉polynomial rings的概念(虽然维基百科的文章太技术化,无法做出最好的介绍)。你似乎遇到的最基本的问题是,你试图过分模仿二进制移位寄存器,而不是完全理解当你将它视为离散动态系统而不是电路时会发生什么。

二进制移位寄存器是一个聪明的电路,用于计算X^N的剩余部分除以f(X),其中f的所有系数都在环Z/2Z中,只包含0和1的环。这些余数是用欧几里德算法计算的,就像计算整数的余数一样。该模型中LFSR的状态是一些小于f度的多项式。 LFSR的第一个状态是1,第二个状态是X。 LFSR中的每个循环等效乘以X,然后乘以长除法的一步。移位操作是乘法,而抽头是长除法。分部真的是在这里。

[旁白:你可以使用任意环作为这种结构的系数,但零除数作为除数多项式的前导系数的问题使事情复杂化。既然你正在使用一个字段,我只会将字段称为系数。]

如果你使用的是除了比特之外的系数环,你需要考虑长分割的一个步骤。如果除数多项式f看起来像a_k X^k + ...,而新状态g看起来像b_k X^k + ...,则长除法的第一步是计算b_k / a_k。对于一个字段(正如我所假设的),这是一些数字c。所以余数是g - cf,这是一个度为k-1的多项式。剩下的就是你的新州。

(表达式cf是理解维基百科文章让你困惑的部分的关键。你可能想要说服自己,你可以将多项式f除以其前导系数{{1获得另一个多项式,该序列生成的序列只是第一个序列的倍数。)

答案 1 :(得分:0)

你可以在math.stackoverflow.com上询问Galois字段下的乘法,但它的要点是,而不是'bits',每个位是0或1(GF_2),每个'bit'实际上是一个许多符号 - 确切的数字取决于字段的大小。

要从二进制LFSR转换到Galois LFSR,您必须概括“位”和“乘法”的概念,以便在该字段中有意义。 乘法运算字段中的加法也取代app()函数中的XOR。

在二进制版本中,乘法是隐式的;输出位或者乘以0或1,具体取决于是否存在抽头。在一般字段中,抽头本身可以包含与之关联的任何字段元素,然后乘以输出。