我必须解决一个由32个xor方程组成的系统,每个方程涉及32个变量中的15个。 一个看起来像这样:
i[0] = p[0] ^ p[4] ^ p[5] ^ p[10] ^ p[11] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[30] ^ p[31]
i [n]和p [n]是16位整数。
据我所知,我最终会得到一个32x32矩阵(仅包含1和0)和32个结果向量。
显然高斯消除是我所需要的,但我无法解决问题,有人能给我一些关于如何解决这个问题的见解吗?
编辑:这是C ++中的解决方案
void SolveLinearSystem(u8 A[32][32], u8 B[32])
{
int N = 32;
for (int K = 0; K < N; ++K)
{
if( A[K][K] == 0 )
{
for(int i = K + 1; i<N ; ++i )
{
if(A[i][K] != 0)
{
for( int L = 0; L < N; ++L )
{
int s = A[K][L];
A[K][L] = A[i][L];
A[i][L] = s;
}
int s = B[i];
B[i] = B[K];
B[K] = s;
break;
}
}
}
for( int I = 0; I<N; ++I)
{
if( I!=K )
{
if( A[I][K] )
{
int M = 0;
for( M=K; M<N; ++M )
{
A[I][M] = A[I][M] ^ A[K][M];
}
B[I] = B[I] ^ B[K];
}
}
}
}
}
答案 0 :(得分:4)
是的,您可以使用高斯消除来解决此问题。关键是要认识到XOR运算相当于加法模2.所以你写的等式相当于
i[0] = (p[0] + p[4] + ... ) mod 2
然后,您可以将整个系统设置为矩阵方程式
M*p=i mod 2
你可以像往常一样使用高斯消除来解决这个问题,除了你的所有操作都将以模2执行。因为你的矩阵包含很多0,所以你将不得不使用旋转,但除此之外,算法是一样的。
答案 1 :(得分:1)
如果您熟悉解决常规方程组,那么这不是主要步骤。当在方程组中使用实数时,你会像这样消除:
[a b; c d] -> [a b; 0 d-(b*c/a)] -> [a 0; 0 d-(b*c/a)] -> [1 0; 0 1]
注意:这里我使用MATLAB矩阵表示法来简化输入。
要做的重要实现是任何字段都存在所有这些矩阵运算(即除法,乘法,加法和减法),而不仅仅是实数。如果您不熟悉术语 field ,它只是意味着一组允许乘法,否定,反转,加法等的值。
这需要我们解决xor方程组。您目前将系统描述为一堆16位值xor'd。但是,我选择将它表示为一堆xor'd的方式,例如,如果你的第一个等式是:
p[0] = a[1] ^ a[2]
我将此表示为:
p[0][0] = a[1][0] ^ a[2][0]
p[0][1] = a[1][1] ^ a[2][1]
…
其中第二组括号表示16位值中的bit
偏移量。所以,你的每个小方程式都相当于16个方程式。
布尔运算上的单位xor运算形成一个字段。在这个字段中,我们使“加法”运算符等效于xor。我们可以如下定义加法和乘法表:
1 + 0 = 0 + 1 = 1; 1 + 1 = 0 + 0 = 0
1 * 0 = 0 * 1 = 0 * 0 = 0; 1 * 1 = 1
除法只能为1(因为你不能除以零),因此除法运算符会保留一个元素。
有了这个,你应该能够为你的xor方程组形成一个矩阵。该矩阵将完全由1和0组成。然后使用高斯 - 约旦消除算法(实际上并不太难实现)就像普通实数一样。这将允许您反转矩阵并找到解决方案。
我个人对这个问题非常感兴趣,我写了一个小的C ++矩阵实现,允许你提供你喜欢的任何字段。这可能是一个很好的起点,或者您甚至可能希望完全使用我的代码!这是Github上的源代码:XorSystem。我特别建议在ANMatrix上查看invert()方法。