博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解析torrent种子信息
阅读量:7033 次
发布时间:2019-06-28

本文共 9611 字,大约阅读时间需要 32 分钟。

hot3.png

package kan;/* * BeDecoder.java * * Created on May 30, 2003, 2:44 PM * Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. */import java.io.BufferedInputStream;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.Charset;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;/** * A set of utility methods to decode a bencoded array of byte into a Map. * integer are represented as Long, String as byte[], dictionnaries as Map, and * list as List. *  * @author TdC_VgA *  */@SuppressWarnings(value={"rawtypes", "unchecked", "unused"})public class BDecoder {	public static Charset BYTE_CHARSET = Charset.forName("UTF-8");;	    public static Charset DEFAULT_CHARSET = Charset.forName("UTF-8");;		private boolean recovery_mode;		public static Map decode(byte[] data) throws IOException {		return (new BDecoder().decodeByteArray(data));	}	public static Map decode(BufferedInputStream is) throws IOException {		return (new BDecoder().decodeStream(is));	}	public BDecoder() { }	public Map decodeByteArray(byte[] data) throws IOException {		return (decode(new ByteArrayInputStream(data)));	}	public Map decodeStream(BufferedInputStream data) throws IOException {		Object res = decodeInputStream(data, 0);		if (res == null) {			throw (new IOException("BDecoder: zero length file"));		} else if (!(res instanceof Map)) {			throw (new IOException("BDecoder: top level isn't a Map"));		}		return ((Map) res);	}	private Map decode(ByteArrayInputStream data) throws IOException {		Object res = decodeInputStream(data, 0);		if (res == null) {			throw (new IOException("BDecoder: zero length file"));		} else if (!(res instanceof Map)) {			throw (new IOException("BDecoder: top level isn't a Map"));		}		return ((Map) res);	}	private Object decodeInputStream(InputStream bais, int nesting)	throws IOException {		if (nesting == 0 && !bais.markSupported()) {			throw new IOException("InputStream must support the mark() method");		}		// set a mark		bais.mark(Integer.MAX_VALUE);		// read a byte		int tempByte = bais.read();		// decide what to do		switch (tempByte) {		case 'd':			// create a new dictionary object			Map tempMap = new HashMap();			try {				// get the key				byte[] tempByteArray = null;				while ((tempByteArray = 						(byte[]) decodeInputStream(bais,nesting + 1)) != null) {					// decode some more					Object value = decodeInputStream(bais, nesting + 1);					// add the value to the map					CharBuffer cb = 							BYTE_CHARSET.decode(ByteBuffer.wrap(tempByteArray));					String key = new String(cb.array(), 0, cb.limit());					tempMap.put(key, value);				}				bais.mark(Integer.MAX_VALUE);				tempByte = bais.read();				bais.reset();				if (nesting > 0 && tempByte == -1) {					throw (new IOException(							"BDecoder: invalid input data, 'e' missing from end of dictionary"));				}			} catch (Throwable e) {				if (!recovery_mode) {					if (e instanceof IOException) {						throw ((IOException) e);					}					throw (new IOException(e.toString()));				}			}			// return the map			return tempMap;		case 'l':			// create the list			List tempList = new ArrayList();			try {				// create the key				Object tempElement = null;				while ((tempElement = decodeInputStream(bais, nesting + 1)) != null) {					// add the element					tempList.add(tempElement);				}				bais.mark(Integer.MAX_VALUE);				tempByte = bais.read();				bais.reset();				if (nesting > 0 && tempByte == -1) {					throw (new IOException(							"BDecoder: invalid input data, 'e' missing from end of list"));				}			} catch (Throwable e) {				if (!recovery_mode) {					if (e instanceof IOException) {						throw ((IOException) e);					}					throw (new IOException(e.toString()));				}			}			// return the list			return tempList;		case 'e':		case -1:			return null;		case 'i':			return new Long(getNumberFromStream(bais, 'e'));		case '0':		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':			// move back one			bais.reset();			// get the string			return getByteArrayFromStream(bais);		default: {			int rem_len = bais.available();			if (rem_len > 256) {				rem_len = 256;			}			byte[] rem_data = new byte[rem_len];			bais.read(rem_data);			throw (new IOException("BDecoder: unknown command '" + tempByte					+ ", remainder = " + new String(rem_data, DEFAULT_CHARSET)));		}		}	}	private long getNumberFromStream(			InputStream bais, char parseChar)throws IOException {		StringBuffer sb = new StringBuffer(3);		int tempByte = bais.read();		while ((tempByte != parseChar) && (tempByte >= 0)) {			sb.append((char) tempByte);			tempByte = bais.read();		}		// are we at the end of the stream?		if (tempByte < 0) {			return -1;		}		return Long.parseLong(sb.toString());	}	// This one causes lots of "Query Information" calls to the filesystem	private long getNumberFromStreamOld(			InputStream bais, char parseChar) throws IOException {		int length = 0;		// place a mark		bais.mark(Integer.MAX_VALUE);		int tempByte = bais.read();		while ((tempByte != parseChar) && (tempByte >= 0)) {			tempByte = bais.read();			length++;		}		// are we at the end of the stream?		if (tempByte < 0) {			return -1;		}		// reset the mark		bais.reset();		// get the length		byte[] tempArray = new byte[length];		int count = 0;		int len = 0;		// get the string		while (count != length				&& (len = bais.read(tempArray, count, length - count)) > 0) {			count += len;		}		// jump ahead in the stream to compensate for the :		bais.skip(1);		// return the value		CharBuffer cb = 				DEFAULT_CHARSET.decode(ByteBuffer.wrap(tempArray));		String str_value = new String(cb.array(), 0, cb.limit());		return Long.parseLong(str_value);	}	private byte[] getByteArrayFromStream(			InputStream bais) throws IOException {		int length = (int) getNumberFromStream(bais, ':');		if (length < 0) {			return null;		}		// note that torrent hashes can be big (consider a 55GB file with 2MB		// pieces		// this generates a pieces hash of 1/2 meg		if (length > 8 * 1024 * 1024) {			throw new IOException("Byte array length too large (" + length + ")");		}		byte[] tempArray = new byte[length];		int count = 0;		int len = 0;		// get the string		while (count != length				&& (len = bais.read(tempArray, count, length - count)) > 0) {			count += len;		}		if (count != tempArray.length) {			throw (new IOException(					"BDecoder::getByteArrayFromStream: truncated"));		}		return tempArray;	}	public void setRecoveryMode(boolean r) {		recovery_mode = r;	}	private void print(PrintWriter writer, Object obj) {		print(writer, obj, "", false);	}	private void print(			PrintWriter writer, Object obj, String indent, boolean skip_indent) {		String use_indent = skip_indent ? "" : indent;		if (obj instanceof Long) {			writer.println(use_indent + obj);		} else if (obj instanceof byte[]) {			byte[] b = (byte[]) obj;			if (b.length == 20) {				writer.println(use_indent + " { " + b + " }");			} else if (b.length < 64) {				writer.println(new String(b, DEFAULT_CHARSET));			} else {				writer.println("[byte array length " + b.length);			}		} else if (obj instanceof String) {			writer.println(use_indent + obj);		} else if (obj instanceof List) {			List l = (List) obj;			writer.println(use_indent + "[");						for (int i = 0; i < l.size(); i++) {				writer.print(indent + "  (" + i + ") ");				print(writer, l.get(i), indent + "    ", true);			}			writer.println(indent + "]");		} else {			Map m = (Map) obj;			Iterator it = m.keySet().iterator();			while (it.hasNext()) {				String key = (String) it.next();				if (key.length() > 256) {					writer.print(indent + key.substring(0, 256) + "... = ");				} else {					writer.print(indent + key + " = ");				}				print(writer, m.get(key), indent + "  ", true);			}		}	}	private static void print(File f, File output) {		try {			BDecoder decoder = new BDecoder();			decoder.setRecoveryMode(false);			PrintWriter pw = new PrintWriter(new FileWriter(output));			decoder.print(pw, 					decoder.decodeStream(							new BufferedInputStream(new FileInputStream(f))));			pw.flush();		} catch (Throwable e) {		}	}	public static void main(String[] args) {//		print(new File(//				"C:\\Temp\\8565658FA6C187A602A5360A69F11933624DD9B5.dat.bak"),//				new File("C:\\Temp\\bdecoder.log"));		//print(new File("D:/Users/Desktop/WorkSpace/torrent/1.torrent"), new File("D:/Users/kanlianhui689/Desktop/WorkSpace/torrent/1.text"));		print(new File("D:/Users/Desktop/WorkSpace/torrent/1.torrent"), new File("D:/Users/kanlianhui689/Desktop/WorkSpace/torrent/1.text"));			}}

转载于:https://my.oschina.net/kanlianhui/blog/168397

你可能感兴趣的文章
hdu 5676 ztr loves lucky numbers
查看>>
angularjs中下拉框select option默认值
查看>>
SPEC2006移入docker后的运行问题
查看>>
poi 操作excel
查看>>
去哪网第一题
查看>>
wufabuquan
查看>>
CentOS 6.5 安装Nginx 1.7.4
查看>>
commander.js 制作简易的 MINA CLI 脚手架
查看>>
召回率与精确率
查看>>
HDU 1573~3579 X问题&Hello Kiki[同余方程]
查看>>
[SDOI2017]数字表格
查看>>
[八省联考2018]劈配
查看>>
antlr.collections.AST.getLine()I异常
查看>>
霍夫曼树
查看>>
使用Go语句生成数值表
查看>>
抛出类类型的异常
查看>>
(visual)c++ 内存分配
查看>>
bootstrap 有些控件需要调用锚点,会与angular 路由 冲突
查看>>
oracle decode函数
查看>>
Fixed Effect
查看>>