【问题标题】:What is wrong with this implementation of bitwise multiplication?这种按位乘法的实现有什么问题?
【发布时间】:2016-11-17 16:39:40
【问题描述】:

为了构建 AES 的实现,我正在尝试在 Galois 域 256 中实现按位乘法的方法。我目前的乘法方法如下:

public static int multiplyPolynomials(int n, int m)
{
int result = 0x00000000;
String ns = toBitString(n);
String ms = toBitString(m);

for (int i = 0; i < ns.length(); i++)
{
    if (ns.charAt(i) == '1')
    {
        /*
         * If there's a 1 at place i, add the value of m left-shifted i places to the result.
         */
        int temp = m;
        for (int j = 0; j < i; j++) { temp = temp << 1; } 
        result += temp;
    }
}
return result;
}

toBitString(int n) 方法纯粹是Integer.toBinaryString(int n) 的快捷方式。

给定输入(0x0000ef00, 2),这个函数的输出是494(应该是478)。打印对toBitString(0x0000ef00) 的直接调用确认该函数的输出符合预期(在本例中为 1110111100000000)。如果第一个输入向右移动一个字节(0x000000ef),输出仍然是 494。

使用上述输入,ns 的值为1110111100000000result 的位串等价物为111101110ns 因此是正确的。

上面的方法有什么错误?

【问题讨论】:

  • 所以据我了解,您遇到的问题是 ms,但我看不到它的任何用法!另外请您解释一下计算结果背后的机制是什么?
  • ms 实际上此时并未使用。据我所知,问题一定出在最里面的for 循环中,但我不知道它是什么。 (虽然我刚刚意识到使用&lt;= 是一个问题,因为它转换的次数太多了。)

标签: java bit-manipulation


【解决方案1】:

您以错误的方式读取二进制字符串。

试试这个...

public static int multiplyPolynomials(int n, int m) {
    int result = 0x00000000;
    String ns = Integer.toBinaryString(n);

    for (int i = 0; i < ns.length(); i++) {
        // Read the string the other way round...
        int bitIndex = (ns.length() - i) - 1;
        if (ns.charAt(bitIndex) == '1') {
            /*
             * If there's a 1 at place i, add the value of m left-shifted i
             * places to the result.
             */
            int temp = m;
            // Don't need a loop here, just shift it by "i" places
            temp = temp << i;
            result += temp;
        }
    }
    return result;
}

除了将数字转换为二进制字符串之外,您还可以使用类似的东西...

public static int multiplyPolynomials(int n, int m) {
    int result = 0x00000000;

    for (int i = 0; i < 32; i++) {
        int mask = 1 << i;

        if ((n & mask) == mask) {
            result += m << i;
        }
    }
    return result;
}

您可能需要将答案存储为 long 以防止溢出,并且它可能不适用于负数...

【讨论】:

  • Aaaaa 做到了。在编写方法之前,我曾积极考虑过需要颠倒迭代顺序,但显然还是忘记了。
猜你喜欢
  • 2013-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多