【问题标题】:Modulus power of big numbers大数的模幂
【发布时间】:2012-01-07 09:34:02
【问题描述】:

我正在尝试实现 SAFER+ 算法。该算法需要如下求幂函数的模:

pow(45, x) mod 257

变量 x 是一个字节,因此范围可以从 0 到 255。因此,如果使用 32 位或 64 位整数实现,幂函数的结果可能非常大,从而导致不正确的值。

我该如何执行这个计算?

【问题讨论】:

  • @esskar:如果我没有完全弄错并且没记错的话,在模空间中有计算能力的特殊公式,模演算是问题的重要部分,所以这个问题与语言无关.
  • 介绍性阅读:The multiplicative group of integers。这太久远了,我无法回答,但也许有人记得。
  • 有一个用 C 编写的 SAFER+ 实现,您可以在这里学习:schneier.com/book-applied-source.html

标签: algorithm math language-agnostic modulus


【解决方案1】:

一些伪代码

function powermod(base, exponent, modulus) {
    if (base < 1 || exponent < 0 || modulus < 1)
        return -1

    result = 1;
    while (exponent > 0) {
       if ((exponent % 2) == 1) {
           result = (result * base) % modulus;
       }
       base = (base * base) % modulus;
       exponent = floor(exponent / 2);
    }
    return result;
}

然后打电话

powermod(45, x, 257)    

【讨论】:

    【解决方案2】:

    通过重复平方执行求幂,每次操作后按模数减少。这是一种非常标准的技术。

    一个工作示例:45^13 mod 257:

    1. 首先计算 45^2、45^4、45^8 mod 257:

      45^2 模 257 = 2025 模 257 = 226

      45^4 mod 257 = 226^2 mod 257 = 51076 mod 257 = 190

      45^8 mod 257 = 190^2 mod 257 = 36100 mod 257 = 120

    2. 然后用13的二进制展开将这些组合起来得到结果:

      45^13 模 257 = 45^1 * 45^4 * 45^8 模 257

      45^13 模 257 = 45 * 190 * 120 模 257

      45^13 模 257 = 8550 * 120 模 257

      45^13 模 257 = 69 * 120 模 257

      45^13 模 257 = 8280 模 257

      45^13 模 257 = 56

    请注意,计算的中间结果永远不会大于 257*257,因此可以轻松地以 32 位整数类型执行。

    【讨论】:

      【解决方案3】:

      基本方法是根据指数位进行平方或相乘,并在每一步执行模归约。该算法称为(binary) modular exponentiation

      【讨论】:

        【解决方案4】:

        考虑简单的身份:

        mod(A^2,p) = mod(A,p)*mod(A,p)
        

        还要注意

        A^4 = (A^2)^2
        

        如果您知道要计算的最终指数的二进制表示,则可以轻松计算其他幂。

        【讨论】:

          猜你喜欢
          • 2017-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多