所以。我在JS中的其他for循环中有4个for循环,并且我的代码显示(FireBug同意我的观点)我的代码在语法上是正确的,但是它拒绝工作。我正在尝试通过使用巧合指数和Kappa测试来计算vigenere密码中的密钥长度,如果这有任何帮助的话。
我的主要问题是,对于Javascript来说,这个任务的计算密集度似乎太高了,因为Firefox占用了超过1 1GB的内存,当我试图运行keylengthfinder()函数时,占用了99%的CPU。任何关于如何解决这个问题的想法,即使它需要更长的计算时间,都将非常感谢。这里有一个指向相同代码的链接- 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;
}发布于 2012-07-18 07:36:36
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] = ...
}在这个循环中,您计算从z到textL的i的值-但是每次都覆盖相同的数组项。所以计算i=textL-1的stringtable[z]就足够了--否则你的算法是有缺陷的。
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检测到的case 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;
}每个循环语句都针对原始脚本进行了更改!
run keyword)
a
var0 to n-1,var0 to n -1,i=0; i<n; i++ (几乎所有的循环,特别是在基于零的数组循环上),这两个循环在正常程序中是不会出现的。如果您有从0到n或从1到n-1的循环,您应该会怀疑...i++是i+=1的快捷方式,是i=i+1的快捷方式。您的表达式i + a没有赋予新值(除了a=0问题)!发布于 2012-07-18 07:45:49
你的问题就在这里
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,i永远不会改变,因此您处于无限循环中。
https://stackoverflow.com/questions/11532177
复制相似问题