1

それで。JSのforループの中に4つのforループがあり、私のコードは構文的に健全であるように見えますが(FireBugは私に同意します)、それでも機能しません。Index of Coincidenceを使用して、ヴィジュネル暗号の鍵長を計算しようとしています。カッパテスト<-それが役立つ場合。

私の主な問題は、Firefoxがkeylengthfinder()関数を実行しようとすると、1GBを超えるメモリ使用量と99%のCPUを消費するため、このタスクは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=0私が決して変わらないので、あなたは無限ループにいることに注意してください。

于 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常に1人のキャラクターになりますか?

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

このループでは、ifromzからtextL-の値を計算していますが、毎回同じ配列項目を上書きします。したがって、for-を計算するだけで十分です。そうでないstringtable[z]場合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;
}

わかった。問題(qw3nで検出された場合の無限ループを含む)が見つかったのでa=0、ループを書き直してみましょう。

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++(特にゼロベースの配列表示では、ほぼすべてのループ)。
  • これらの2つ以外のループは、通常のプログラムでは発生しません。0からnまたは1からn-1のループがある場合は、疑わしいと思うはずです。
  • 更新式は、実行変数を更新する必要があります。i++のショートカットです。i+=1のショートカットですi=i+1。あなたの表現はi + a、(問題は別として)新しい値を割り当てませんでしa=0た!
于 2012-07-17T23:36:36.463 に答える