翻代码翻出n年前写的东西,当初还想做个tracker的,还去sourceforge申请个项目,没通过。。。怀念一下:
import java.util.*;
public class BitDecoder
{
//0
public static final byte ZERO_BYTE = 0x30;
//9
public static final byte NINE_BYTE = 0x39;
//-
public static final byte MINUS_BYTE = 0x2D;
//:
public static final byte COLON_BYTE = 0x3A;
//d
public static final byte d_BYTE = 0x64;
//e
public static final byte e_BYTE = 0x65;
//i
public static final byte i_BYTE = 0x69;
//l
public static final byte l_BYTE = 0x6c;
//n
public static final byte NULL_BYTE = 0x6e;
//最大解释层数
public static int MAX_LAYER = 8;
private int now_layer = 0;
private String index_key = “”;
private int key_start = 0;
private int key_end = 0;
public BitDecoder(String key)
{
if(key!=null)
index_key = key;
}
public void reset(String key)
{
now_layer = 0;
key_start = 0;
key_end = 0;
if(key!=null)
index_key = key;
else
index_key = “”;
}
public String getkey()
{
return index_key;
}
public int getKeyStart()
{
return key_start;
}
public int getKeyEnd()
{
return key_end;
}
//解出int,用String保存
private BTDecodeObj decode_int(byte [] bytes,int index) throws Exception
{
int till_index = ++index;
byte workingbyte = bytes[till_index];
if(workingbyte == MINUS_BYTE)
{
workingbyte = bytes[till_index+1];
if(workingbyte == ZERO_BYTE)
throw new Exception(“number -0 is not allowed”);
else if(workingbyte == e_BYTE)
throw new Exception(“only minus is not allowed”);
else if(workingbyte>NINE_BYTE || workingbyte<ZERO_BYTE)
throw new Exception(“number must be 0-9”);
else
till_index++;
}
while(true)
{
workingbyte = bytes[till_index];
if(workingbyte == e_BYTE)
break;
else if(workingbyte>NINE_BYTE || workingbyte<ZERO_BYTE)
throw new Exception(“number must be 0-9”);
else
till_index++;
}
if(bytes[index]==ZERO_BYTE && till_index!=index+1)
throw new Exception(“number 0 must be alone”);
else
return new BTDecodeObj(new String(bytes,index,till_index-index),till_index+1);
}
//解出String
private BTDecodeObj decode_string(byte [] bytes,int index) throws Exception
{
int colon_index = index;
byte workingbyte = 0x00;
while(true)
{
workingbyte = bytes[colon_index];
if(workingbyte == COLON_BYTE)
break;
else if(workingbyte>NINE_BYTE || workingbyte<ZERO_BYTE)
throw new Exception(“string length must be 0-9”);
else
colon_index++;
}
if(bytes[index] == ZERO_BYTE && colon_index!=index+1)
throw new Exception(“string length 0 must follow by :”);
index = Integer.parseInt(new String(bytes,index,colon_index-index));
colon_index++;
return new BTDecodeObj(new String(bytes,colon_index,index,”8859_1″),colon_index+index);
}
//解出List
private BTDecodeObj decode_list(byte [] bytes,int index) throws Exception
{
now_layer++;
if(now_layer > MAX_LAYER)
throw new Exception(“too many list or dictionary layer!”);
index++;
ArrayList resultlist = new ArrayList();
BTDecodeObj tempobj = null;
while(bytes[index] != e_BYTE)
{
tempobj = bdecode(bytes,index);
index = tempobj.getIndex();
resultlist.add(tempobj.getObj());
}
now_layer–;
return new BTDecodeObj(resultlist,index+1);
}
//解出dict
private BTDecodeObj decode_dict(byte [] bytes,int index) throws Exception
{
now_layer++;
if(now_layer > MAX_LAYER)
throw new Exception(“too many list or dictionary layer!”);
index++;
HashMap resultmap = new HashMap();
BTDecodeObj tempobj = null;
String lastkey = “”;
String nowkey = null;
while(bytes[index] != e_BYTE)
{
tempobj = decode_string(bytes,index);
nowkey = (String)tempobj.getObj();
if(nowkey.compareTo(lastkey) <= 0)
throw new Exception(“dictionary lexicographically order error!”);
lastkey = nowkey;
index = tempobj.getIndex();
if(key_start==0 && index_key.equals(lastkey))
{
key_start = index;
}
tempobj = bdecode(bytes,index);
index = tempobj.getIndex();
if(key_start!=0 && index_key.equals(lastkey))
{
key_end = index;
}
resultmap.put(nowkey,tempobj.getObj());
}
now_layer–;
return new BTDecodeObj(resultmap,index+1);
}
private BTDecodeObj bdecode(byte [] bytes,int index) throws Exception
{
if(bytes[index]>=ZERO_BYTE && bytes[index]<=NINE_BYTE)
return decode_string(bytes,index);
else if(bytes[index] == d_BYTE)
return decode_dict(bytes,index);
else if(bytes[index] == l_BYTE)
return decode_list(bytes,index);
else if(bytes[index] == i_BYTE)
return decode_int(bytes,index);
else
throw new Exception(“torrent bencode format error!”);
}
public Object bdecode(byte [] bytes) throws Exception
{
BTDecodeObj resultobj = bdecode(bytes,0);
if(resultobj.getIndex() != bytes.length)
throw new Exception(“torrent bencode format error,length exception!”);
return resultobj.getObj();
}
public int getNowLayer()
{
return now_layer;
}
public static class BTDecodeObj
{
Object obj = null;
int index = 0;
public BTDecodeObj(Object obj,int index)
{
this.obj = obj;
this.index = index;
}
public Object getObj()
{
return obj;
}
public int getIndex()
{
return index;
}
}
}
Leave a Reply