CTF-wiki中的题目
主要通过概率统计解题。在解题过程中,因为只给出了小写英文字母出现的概率,所以需要将大写字母转成小写字母,来获得字母出现概率。
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import static javax.swing.UIManager.put;
public class Characterfrequency
{
//a-z字母在英文字母中出现的概率
static Map<Character, Double> scnum=new HashMap<Character, Double>(){{
put('a',0.0651738);put('b',0.0124248);put( 'c',0.0217339);put( 'd',0.0349835);put( 'e',0.1041442); put( 'f',0.0197881);put( 'g',0.0158610);
put( 'h',0.0492888);put('i',0.0558094);put('j',0.0009033);put('k',0.0050529);put('l',0.0331490);put('m',0.0202124);put('n',0.0564513);
put('o',0.0596302);put('p',0.0137645);put('q',0.0008606);put('r',0.0497563);put( 's',0.0515760);put( 't',0.0729357);put( 'u',0.0225134);
put( 'v',0.0082903);put( 'w',0.0171272);put('x',0.0013692);put( 'y',0.0145984);put( 'z',0.0007836);put( ' ',0.1918182);}};
static double[] allresult=new double[52];
public static void strfrequency(int[] plaintext,int num)
{
for(int i=0;i<plaintext.length;i++)
{
//A-Z
if(plaintext[i]>=65 && plaintext[i]<=90)
{
plaintext[i]=plaintext[i]+32;
}
if(scnum.containsKey((char)plaintext[i]))
{
allresult[num] = allresult[num] + scnum.get((char)plaintext[i]);
}
}
}
public static void main()
{
String cipher="1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
int[] tempresult=new int[cipher.length()/2];
//大写A-Z
for(int i=65;i<=90;i++)
{
for(int j=0;j<cipher.length()/2;j++)
{
tempresult[j]=(Integer.parseInt(cipher.substring(j*2,j*2+2),16)^i);
}
strfrequency(tempresult,i-65);
}
//小写a-z
for(int i=97;i<=122;i++)
{
for(int j=0;j<cipher.length()/2;j++)
{
tempresult[j]=(Integer.parseInt(cipher.substring(j*2,j*2+2),16)^i);
}
strfrequency(tempresult,i-97+26);
}
double max=allresult[0];
int maxnum=0;
for(int i=1;i<52;i++)
{
if(allresult[i]>max)
{
max=allresult[i];
maxnum=i;
}
}
if(maxnum<25)
{
maxnum=maxnum+65;
}
else {
maxnum=maxnum+71;
}
byte[] result=new byte[cipher.length()/2];
for(int j=0;j<cipher.length()/2;j++)
{
//substring不包括j*2+2 +2是指这个字符串长度为2
result[j]=Integer.valueOf((Integer.parseInt(cipher.substring(j*2,j*2+2),16)^maxnum)).byteValue();
}
String Strresult=new String(result, StandardCharsets.UTF_8);
System.out.println("The Decoded result is:"+Strresult);
return ;
}
}
解码结果:Cooking MC's like a pound of bacon