Vigenère cipher/Cryptanalysis: Difference between revisions

m
→‎{{header|zkl}}: added comments
m (→‎{{header|zkl}}: added comments)
Line 1,621:
=={{header|zkl}}==
{{trans|Python}}
<lang zkl>var[const] uppercase=Utils["A".Helpers.upperLetters"Z"].pump(String),
english_frequences=T( // A..Z
0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015,
Line 1,627:
0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758,
0.00978, 0.02360, 0.00150, 0.01974, 0.00074);
 
fcn vigenere_decrypt(target_freqs, input){ // ( (float,...), string)
nchars,ordA :=uppercase.len(),"A".toAsc();
sorted_targets:=target_freqs.sort();
frequency:='wrap(input){ // (n,n,n,n,...), n is ASCII index ("A"==65)
result:=uppercase.pump(List().write,fcn(c){ List.fp1(c,0.0) }); // -->mutable( ("A",0),("B",0) ...)
foreach c in (input){ result[c - ordA][1] += 1 }
result // --> mutable list of mutable lists ( ("A",Int)...("Z",Int) )
result
};
correlation:='wrap(input){ // (n,n,n,n,...), n is ASCII index ("A"==65)
result,freq:=0.0, frequency(input);
freq.sort(fcn([(_,a)],[(_,b)]){ a<b }); // sort letters by frequency
foreach i,f in (freq.enumerate()){ result+=fsorted_targets[1i]*sorted_targetsf[i1] }
result // -->Float
};
cleaned:=input.toUpper().pump(List,uppercase.holds,Void.Filter,"toAsc");
 
best_len,best_corr := 0,-100.0;
# Assume that if there are less than 20 characters
# per column, the key's too long to guess
foreach i in ([2..cleaned.len()/20]){
pieces:=(i).pump(List,List.copy); // ( (),() ... )
foreach j,c in (cleaned.enumerate()){ pieces[j__cWalker.idx%i].append(c) }
# The correlation seems to increase for smaller
Line 1,661:
pieces:=best_len.pump(List,List.copy);
foreach i,c in (cleaned.enumerate()){ pieces[i__cWalker.idx%best_len].append(c) }
key,freqs := "",pieces.apply(frequency);
key:="";
foreach fr in (freqs){
fr.sort(fcn([(_,a)],[(_,b)]){ a>b }); // reverse sort by freq
m,max_corr := 0,0.0;
foreach j in (nchars){
corr,c := 0.0,ordA + j;
foreach frc in (fr){
d:=(frc[0].toAsc() - c + nchars) % nchars;
corr+=frctarget_freqs[1d]*target_freqsfrc[d1];
 
if(corr>max_corr) m,max_corr=j,corr;
}
Line 1,680 ⟶ 1,677:
key+=(m + ordA).toChar();
}
 
cleaned.enumerate().apply('wrap([(i,c])){
( (c - (key[i%best_len]).toAsc() + nchars)%nchars + ordA ).toChar()
Anonymous user