我目前的实现如下,取自this question并修改为使用独占或替代添加,如此处的评论。假设(并且,对于此实现的目标,可接受),所有输入矩阵将是4x4。
/**
* Produces the product of two matrices, treating the first parameter as the "left" matrix.
*/
public static int[][] multiplyMatrices(int[][] a, int[][] b)
{
int[][] resultMatrix = new int[4][4];
for (int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
for(int k = 0; k < 4; k++)
{
resultMatrix[i][j] = resultMatrix[i][j] ^ multiplyPolynomials(a[i][k], b[k][j]);
}
}
}
return resultMatrix;
}
multiplyPolynomials
功能如here所述。
/**
* Multiplies two polynomials (mod 2) represented as integers.
* The first is converted into a binary string, which is then used
* to select a number of appropriate bit shifts of the
* second, which are then added together.
*/
public static int multiplyPolynomials(int n, int m)
{
int result = 0x00000000;
String ns = toBitString(n);
for (int i = 0; i < ns.length(); i++)
{
int bitIndex = (ns.length() - i) -1;
if (ns.charAt(bitIndex) == '1')
{
int temp = m;
temp = temp << i;
result = result ^ temp;
}
}
return result;
}
运行multiplyMatrices
后,resultMatrix
作为reduceMatrix
的参数传递,定义如下,第二个参数为0x011b。 (toBitString
只是Integer.toBinaryString
的快捷方式。)
/*
* Reduces all elements of the matrix modulo a given polynomial.
* Treats the values as bit-string representations of polynomials mod 2.
* Works by XORing various left-shifts of the modulo value with the value being reduced.
* NOTE: This comment describes both reduceMatrix() and moduloReduce().
*/
public static int[][] reduceMatrix(int[][] m, int p)
{
int[][] reducedM = new int[4][4];
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
reducedM[i][j] = moduloReduce(m[i][j], p);
}
}
return reducedM;
}
public static int moduloReduce(int f, int p)
{
String fs = toBitString(f);
String ps = toBitString(p);
int temp = f;
int q = 0;
while (toBitString(temp).length() >= ps.length())
{
int j = toBitString(temp).length()-1;
int k = ps.length()-1;
q = p << (j-k);
temp = temp ^ q;
}
return temp;
}
使用以下两个矩阵作为输入进行测试,给出的值显式为十六进制:
02 03 01 01
01 02 03 01
01 01 02 03
03 01 01 02
----------
10 26 03 15
23 41 33 04
51 32 14 43
12 12 12 12
使用这些输入,输出矩阵(十六进制,缩减mod 0x011b)为:
10 26 03 15
23 41 33 04
51 32 14 43
12 12 12 12
但是,手动完成减少会产生不同的结果:
06 af 55 7c
b7 e0 4b ca
a7 35 2e a1
66 3d 06 5c
很明显,编写的程序无法正常工作。但是,以下第二个输入矩阵(使用相同的第一个矩阵)将返回正确的结果:
30 ca 96 24
32 92 09 23
3f ca 43 63
7d 5a f8 96
上述输入的预期(和收到)结果如下:
74 b2 97 d8
68 ea b9 51
fb 39 0a 60
a7 a9 00 1b
显然,multiplyMatrices
的输出并非所有情况下的预期结果。使用的矩阵乘法算法似乎适用于链接问题的海报,我之前已经验证multiplyPolynomials
按预期工作。 multiplyMatrices
输出不准确的最可能原因是什么?为什么有些输入会产生正确的输出呢?