【问题标题】:Miller Rabin Primality Test Error on JavaScriptJavaScript 上的 Miller Rabin 素性测试错误
【发布时间】:2017-07-30 01:27:33
【问题描述】:

我正在研究 JavaScript 以使三种不同的算法在同一代码中工作,我为每种算法设置了一个函数。我正在尝试获得三种素性测试方法:试除法、费马素性测试和米勒-拉宾素性测试。前两个工作正常,但米勒拉宾不是。总的来说,我对 JavaScript 和编程很陌生,所以如果你能找到我出错的地方或者想办法让它工作,请告诉我!谢谢!

// 1531 6389 68819 688889 6388819
// 68883889 688838831 1000000009
// 561 is a Carmichael number; a Fermat pseudoprime with the property a^n-1 = 1 mod n, for any "a" coprime to 561.
input = 5491763;
numTrials = 2000;

document.getElementById("input").innerHTML = input;

function TrialDiv(n) {

  if (n === 1) {
    return false;
  } else if (n === 2) {
    return true;
  } else {
    for (var x = 2; x < n; x++) {
      if (n % x === 0) {
        return false;
      }
    }
    return true;
  }
}

if ((TrialDiv(input)) === true) {
  a = "Prime"
} else if ((TrialDiv(input)) === false) {
  a = "Composite"
}
//---------------------------------------------------------------------------
function gcd(x, y) {
  while (y !== 0) {
    var z = x % y;
    x = y;
    y = z;
  }
  return x;
}

function getRndInteger(max) {
  return Math.floor(Math.random() * (max - 2)) + 2;
}
//--------------------------------------------------------------------------
function Fermat(n) {

  for (var t = 0; t = numTrials; t++) {
    m = getRndInteger(input);
    if (gcd(m, n) !== 1) {
      return false;
    }
  }
  return (Math.pow(m, n - 1) % n !== 1);
}

if ((Fermat(input)) === true) {
  b = "Prime";
} else if ((Fermat(input)) === false) {
  b = "Composite";
}
//---------------------------------------------------------------------------
function genD(n) { // Generates "d" such that "n-1 = 2^s * d"
  var p = n - 1;
  var d = p / 2;
  while (d % 2 === 0) {
    d = d / 2;
  }
  return d;
}

function genS() { // Generates "s" such that "n-1 = 2^s * d"
  var s = Math.log2(p / d);
  return s;
}
//---------------------------------------------------------------------------
function MillerRabin(n) {

  for (var t = 0; t < numTrials; t++) {
    m = getRndInteger(input);
    if (gcd(m, n) !== 1) {
      return false;
    } else {
      for (var r = 0; r < genS(); r++) {
        power = (Math.pow(2, r) * genD(input));
        if (Math.pow(m, genD(input)) % n === 1 || Math.pow(m, power) % n === -1) {
          return true;
        } else {
          return false;
        }
      }
      return true;
    }
    return true;
  }
}

if ((MillerRabin(input)) === true) {
  c = "Prime";
} else if ((MillerRabin(input)) === false) {
  c = "Composite";
}
<body>
  <button type="button" onclick='document.getElementById("TrialDivision").innerHTML = a;  document.getElementById("FermatTest").innerHTML = b; document.getElementById("MillerRabinTest").innerHTML = c; '>Show</button>

  <hr>
  <b style="color:rgb(0,0,120)">PRIMALITY TESTS</b>
  <p></p>
  Input:
  <l id="input"></l>

  <hr>
  <h5 style="color:rgb(160,0,0)">TRIAL DIVISION</h5>
  <p></p>
  Output:
  <i id="TrialDivision"></i>

  <hr>
  <h5 style="color:rgb(160,0,0)">FERMAT PRIMALITY TEST</h5>
  <p></p>
  Output:
  <i id="FermatTest"></i>

  <hr>
  <h5 style="color:rgb(160,0,0)">MILLER-RABIN PRIMALITY TEST</h5>
  <p></p>
  Output:
  <i id="MillerRabinTest"></i>
</body>
<script>

我就是这么写的,这纯粹是我根据每个测试的原始数学算法创建的。发生的情况是,当输入数为素数时,Miller-Rabin 输出不显示任何内容;该算法无法识别它。但它确实可以正确识别复合材料。

请告诉我您想到的任何改进!

【问题讨论】:

  • 你做了什么调试?错误来自哪里?
  • 当输入数为素数时,Miller-Rabin“输出”不显示任何内容,但正确识别复合数。
  • 你应该修正你的缩进。您可能在某处的分支中遗漏了 return 语句。很难判断什么时候缩进不正确。
  • 感谢您的提示,我刚刚对其进行了编辑并进行了整理以更好地显示缩进。之前想到了缺少退货的问题,查了一下,但是想不出哪里可能会丢失。
  • 当你说它不显示任何东西时,具体是什么MillerRabin函数的输出?

标签: javascript html


【解决方案1】:

你有一些循环不运行的问题。我不确定该算法应该如何工作,所以我不知道它是否工作,但直接的问题是由泄漏变量和未在函数中声明的变量(这使得它们成为全局变量)引起的。

解决这个直接问题的方法是在函数中声明局部变量,这样您就不必依赖其他函数来设置它们。

function genD(n) { // Generates "d" such that "n-1 = 2^s * d"
    var p = n - 1;
    var d = p / 2;
    while (d % 2 === 0) {
        d = d / 2;
    }
    return d;
}

function genS(n) { // Generates "s" such that "n-1 = 2^s * d"
    var p = n - 1
    var d = p / 2
    var s = Math.log2(p / d);
    return s;
}

一旦您开始修复导致崩溃的错误,就会出现其他一些大问题。例如,您的 fermat() 可能永远运行:

for (var t = 0; t = numTrials; t++) {

应该是:

for (var t = 0; t == numTrials; t++) {

= 将每个循环的 t 设置为 numTrails

我认为你应该从头开始,将所有函数和调用这些函数的所有其他逻辑代码放在一起,这样你就可以看到发生了什么。

【讨论】:

  • 是的@AgusPerezDelCastillo - 还有很多其他问题,请参阅更新。
  • 所以我将 MillerRabin 中的 return true 更改为在 for 循环之外,并且它起作用了。但是当我对 Fermat 做同样的事情时,整个事情让我的浏览器崩溃了......
  • 你修复了 Fermat 中的 t == numTrials 吗?
  • 哦,我刚看到更新,非常感谢,如果我有点慢,抱歉,正如我在帖子中所说,我对整个编程世界真的很陌生。
  • 我现在正在解决这个问题。
猜你喜欢
  • 2013-06-09
  • 1970-01-01
  • 2016-02-27
  • 2019-10-04
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多