1

所以。我在 JS 中的其他 for 循环中有 4 个 for 循环,并且我的代码出现(FireBug 同意我的观点)我的代码在语法上是合理的,但它拒绝工作。我正在尝试通过使用巧合索引和 Kappa 测试来计算 vigenere 密码中的密钥长度<-如果有帮助的话。

我的主要问题是,当我尝试运行 keylengthfinder() 函数时,由于 Firefox 的内存使用量超过 1GB,CPU 超过 99%,因此该任务的计算量似乎太高,无法运行 Javascript。任何关于如何解决这个问题的想法,即使需要更长的时间来计算,也将不胜感激。这是相同代码的链接 - http://pastebin.com/uYPBuZZz - 很抱歉此代码中的任何缩进问题。我在将其正确放置在页面上时遇到问题。

function indexofcoincidence(text){
    text = text.split(" ").join("").toUpperCase();
    var textL = text.length;
    var hashtable = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
    var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    for (d=0; d<=25; d++) {
        for (i=0; i < textL; i++){
            if (text.charAt(i) === alphabet.charAt(d)){
            hashtable[d] = hashtable[d] + 1;
            }
        }
    }

    var aa = hashtable[0]/textL;
    var A = aa*aa;
    var bb = hashtable[1]/textL;
    var B = bb*bb;
    var cc = hashtable[2]/textL;
    var C = cc*cc;
    var dd = hashtable[3]/textL;
    var D = dd*dd;
    var ee = hashtable[4]/textL;
    var E = ee*ee;
    var ff = hashtable[5]/textL;
    var F = ff*ff;
    var gg = hashtable[6]/textL;
    var G = gg*gg;
    var hh = hashtable[7]/textL;
    var H = hh*hh;
    var ii = hashtable[8]/textL;
    var I = ii*ii;
    var jj = hashtable[9]/textL;
    var J = jj*jj;
    var kk = hashtable[10]/textL;
    var K = kk*kk;
    var ll = hashtable[11]/textL;
    var L = ll*ll;
    var mm = hashtable[12]/textL;
    var M = mm*mm;
    var nn = hashtable[13]/textL;
    var N = nn*nn;
    var oo = hashtable[14]/textL;
    var O = oo*oo;
    var pp = hashtable[15]/textL;
    var P = pp*pp;
    var qq = hashtable[16]/textL;
    var Q = qq*qq;
    var rr = hashtable[17]/textL;
    var R = rr*rr;
    var ss = hashtable[18]/textL;
    var S = ss*ss;
    var tt = hashtable[19]/textL;
    var T = tt*tt;
    var uu = hashtable[20]/textL;
    var U = uu*uu;
    var vv = hashtable[21]/textL;
    var V = vv*vv;
    var ww = hashtable[22]/textL;
    var W = ww*ww;
    var xx = hashtable[23]/textL;
    var X = xx*xx;
    var yy = hashtable[24]/textL;
    var Y = yy*yy;
    var zz = hashtable[25]/textL;
    var Z = zz*zz;

    var Kappa = A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z;
    var Top = 0.027*textL;
    var Bottom1 = 0.038*textL + 0.065;
    var Bottom2 = (textL - 1)*Kappa;
    var KeyLength = Top/(Bottom2 - Bottom1) ;

    return Kappa/0.0385;
}

function keylengthfinder(text){
    // Average Function Definition
    Array.prototype.avg = function() {
        var av = 0;
        var cnt = 0;
        var len = this.length;
        for (var i = 0; i < len; i++) {
            var e = +this[i];
            if(!e && this[i] !== 0 && this[i] !== '0') e--;
            if (this[i] == e) {av += e; cnt++;}
    }
        return av/cnt;
    }
    // Begin the Key Length Finding
    var textL = text.length;
    var hashtable = new Array(0,0,0,0,0,0,0,0,0,0,0,0);
        for (a = 0; a <= 12; a++){ // This is the main loop, testing each key length
            var stringtable = [];
            for (z = 0; z <= a; z++){ // This allows each setting, ie. 1st, 4th, 7th AND 2nd, 5th, 8th to be tested
                for (i = z; i < textL; i + a){
                    var string = '';
                    string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
                    stringtable[z] = indexofcoincidence(string);
                    }
                }
            hashtable[a] = stringtable.avg();
        }
    return hashtable;
}
4

2 回答 2

1

你的问题肯定就在这里

for (i = z; i < textL; i + a){
  var string = '';
  string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
  stringtable[z] = indexofcoincidence(string);
 }

请注意,如果a=0i 从未改变,因此您处于无限循环中。

于 2012-07-17T23:45:48.567 回答
0
Array.prototype.avg = function() {...}

应该只做一次,而不是每次都keylengthfinder被调用。

var Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;

如果您根本不使用这些变量,为什么还要计算这些变量?

var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);

我不知道你想在这里做什么。string永远只有一个字符?

for (i = z; i < textL; i + a) {
    ...
    stringtable[z] = ...
}

在此循环中,您正在计算ifrom zto的值textL- 但每次都覆盖相同的数组项。所以计算stringtable[z]for就足够了i=textL-1- 或者你的算法有缺陷。

该函数的一个更短更简洁的变体indexofcoincidence

function indexofcoincidence(text){
    var l = text.replace(/ /g, "").length;
    text = text.toUpperCase().replace(/[^A-Z]/g, "");
    var hashtable = {};
    for (var i=0; i<l; i++) {
        var c = text.charAt(i);
        hashtable[c] = (hashtable[c] || 0) + 1;
    }
    var kappa = 0;
    for (var c in hashtable)
        kappa += hashtable[c] * hashtable[c];
    return kappa/(l*l)/0.0385;
}

好的。现在我们发现了您的问题(包括a=0qw3n 检测到的 case 中的无限循环),让我们重写循环:

function keylengthfinder(text) {
    var length = text.length,
        probabilities = []; // probability by key length
        maxkeylen = 13; // it might make more sense to determine this in relation to length

    for (var a = 1; a <= maxkeylen; a++) { // testing each key length
        var stringtable = Array(a); // strings to check with this gap
        // read "a" as stringtable.length
        for (var z = 0; z < a; z++) {
            var string = '';
            for (var i = z; i < textL; i += a) {
                string += text.charAt(i);
            }
            // a string consisting of z, z+a, z+2a, z+3a, ... -th letters
            stringtable[z] = string;
        }
        var sum = 0;
        // summing up the coincidence indizes for current stringtable
        for (var i=0; i<a; i++) {
            sum += indexofcoincidence(stringtable[i]);
        }
        probabilities[a] = sum / a; // average
    }
    return probabilities;
}

每个循环语句都已针对您的原始脚本进行了更改!

  • 永远不要忘记将运行变量声明为本地(var关键字)
  • a需要从零开始 - 密钥的最小长度必须为 1
  • 要从 1 运行到 n,请使用i=1; i<=n; i++
  • 要从 0 运行到 n-1,请使用i=0; i<n; i++(几乎所有循环,尤其是在从零开始的数组索引上)。
  • 除了这两个之外的其他循环永远不会出现在正常程序中。如果您有从 0 到 n 或从 1 到 n-1 的循环,您应该怀疑...
  • 更新表达式需要更新运行变量。i++是 的快捷方式i+=1是 的快捷方式i=i+1。您的表达式i + a没有分配新值(除了问题a=0)!
于 2012-07-17T23:36:36.463 回答