源代码在这:
import java.io.*;
import java.net.*;public class Attack extends Thread {

static boolean success=false;
final String head="http://211.100.6.141/computer_ebook/0095/C0095";
//for some reasion it's better to give the host IP address than give host name.
final String tail="01.zip";
HttpURLConnection hc;
MidStr ms;

public Attack(MidStr ms) {
this.ms=ms;
}

public void run() {
do {
int rc=-1;//returned status code
String url=null;
try {
url=head+ms.getStr()+tail;
System.out.println("Connecting...."+url);
hc=(HttpURLConnection)(new URL(url).openConnection());
rc=hc.getResponseCode();
}catch(IOException i){}
if(rc==HttpURLConnection.HTTP_OK) {
ms.print(rc,url);
success=true;
break;
}
}while(!success&&ms.hasMore());
}

public static void main(String args[]) {
final int MAXCON=50;
MidStr ms=new MidStr();
for(int i=0;i<MAXCON;i++) {
new Attack(ms).start();
}
}
}
class MidStr {

final static int STRLENGTH=5;
int proc[]=new int[]{3,3,2,1,0};//proc[4]is the first char's index.
final static char[] chars=new char[]{'a','b','c','d','e','f','g','h','j','i','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','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','1','2','3','4','5','6','7','8','9','0'};
boolean more=true;

public boolean hasMore() {
return more;
}

public synchronized void print(int returnedCode,String link) {
System.out.println("Current process is(proc[0]-->proc[4]):"+proc[0]+" "+proc[1]+" "+proc[2]+" "+proc[3]+" "+proc[4]);
System.out.println("Returned code is "+returnedCode);
System.out.println("Link is "+link);
}

synchronized String getStr() {
if(get(0)) {
StringBuffer sb= new StringBuffer(20);
for(int i=STRLENGTH-1;i>=0;i--) {
sb.append(chars[proc[i]]);
}
return sb.toString();
}else return null;
}

private boolean get(int timesRemain) {
boolean succ=false;
while(!succ) {
for(int i=0;i<timesRemain;i++) {
proc[i]=0;
}
proc[timesRemain]++;
for(;proc[timesRemain]<chars.length;proc[timesRemain]++) {
boolean same=false;
for(int i=STRLENGTH-1;i>timesRemain;i--) {
if(proc[timesRemain]==proc[i]) {
same=true;
break;
}
}
if(!same)break;
}
if(proc[timesRemain]>=chars.length)break;
if(timesRemain>0) succ=get(timesRemain-1);
else succ=true;
}
if(succ&&check(timesRemain)) {
return true;
}
if(proc[timesRemain]>=chars.length) {
if(timesRemain<STRLENGTH-1) 
return get(timesRemain+1);
else {
more=false;
return false;
}
}else return get(0);
}

//check(int) is used to discard some impossible string
boolean check(int timesRemain) {
if(timesRemain>0)return true;
int count[]=new int[3];
for(int i=0;i<STRLENGTH;i++) {
if(chars[proc[i]]>='a'&&chars[proc[i]]<='z')count[0]++;
else if(chars[proc[i]]>='A'&&chars[proc[i]]<='Z')count[1]++;
else count[2]++;
}
if(count[0]==STRLENGTH||count[1]==STRLENGTH||count[2]==STRLENGTH) return false;
else return true;
}
}