2019独角兽企业重金招聘Python工程师标准>>>

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 markbais.mark(Integer.MAX_VALUE);// read a byteint tempByte = bais.read();// decide what to doswitch (tempByte) {case 'd':// create a new dictionary objectMap tempMap = new HashMap();try {// get the keybyte[] tempByteArray = null;while ((tempByteArray = (byte[]) decodeInputStream(bais,nesting + 1)) != null) {// decode some moreObject value = decodeInputStream(bais, nesting + 1);// add the value to the mapCharBuffer 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 mapreturn tempMap;case 'l':// create the listList tempList = new ArrayList();try {// create the keyObject tempElement = null;while ((tempElement = decodeInputStream(bais, nesting + 1)) != null) {// add the elementtempList.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 listreturn 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 onebais.reset();// get the stringreturn 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 filesystemprivate long getNumberFromStreamOld(InputStream bais, char parseChar) throws IOException {int length = 0;// place a markbais.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 markbais.reset();// get the lengthbyte[] tempArray = new byte[length];int count = 0;int len = 0;// get the stringwhile (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 valueCharBuffer 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 megif (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 stringwhile (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

解析torrent种子信息相关推荐

  1. Azureus源码剖析(二) ---解析Torrent种子文件

    BT种子文件使用了一种叫bencoding的编码方法来保存数据. bencoding有四种类型的数据:srings(字符串),integers(整数),lists(列表),dictionaries(字 ...

  2. java 解析/读取 种子/bt/torrent 内容

    碰到不会的技术问题,我还是先度娘.能中文看懂,为什么非要看英文呢. java 解析/读取 种子/bt/torrent  内容,这个度娘给的满意答案并不是很多.GG之后的搜索结果出现了stackover ...

  3. linux怎么做bt种子文件,linux 制作BT种子并获取BT种子信息

    最近研究了一下linux BT服务器环境的搭建,需要在linux下制作BT种子并获取BT种子信息,整理了一下这个过程: 制作BT种子软件下载地址:http://jaist.dl.sourceforge ...

  4. linux种子文件制作工具,Centos 制作BT种子并获取BT种子信息

    最近研究了一下linux BT服务器环境的搭建,需要在linux下制作BT种子并获取BT种子信息,整理了一下这个过程: 制作BT种子软件下载地址:http://jaist.dl.sourceforge ...

  5. python解析torrent文件库:pytorrent

    pytorrent是一个非常小巧的用来解析解析torrent文件python库.核心代码不足150行,却能够完备地解析torrent文件,并支持导出修改后的torrent文件. 使用演示: impor ...

  6. POI解析Word批注信息

    前言:报告审批后,要求解析Word批注信息获取 作者.引用正文.批注内容 等信息入库,我这边额外加了回复对象(为后续考虑) 先上代码吧: /*** @author : weiheng* @versio ...

  7. 前端xmp-js解析图片xmp信息

    功能介绍 前端有Exif.js用于解析图像基础信息,但是对于一些比较特殊的图像信息,例如大疆无人机所拍摄得到的图像,它会在图像中添加xmp信息用来保存设备的一些额外信息,例如朝向等等.xmp-js就是 ...

  8. AlphaFold2源码解析(10)--补充信息1(residue_constants)

    AlphaFold2源码解析(10)–补充信息1(residue_constants) 这篇文章总结的很好,来之生信小兔,这里只是收藏一下,转载来源https://blog.csdn.net/weix ...

  9. 群晖Nas通过jellyfin搭建本地影音库详细全过程(四):解析jellyfin视频信息文件NFO

    前言,经过上述刮削之后,电脑里还剩下很多不知名的或者一些个人喜欢的科普视频等,这些视频也很多,难道都要导入tinyMediaManager一个个手动添加视频信息吗?应该看看tinyMediaManag ...

最新文章

  1. 二十五、内存的基础知识
  2. Java方向如何准备BAT技术面试答案
  3. nginx openresty content_by_lua_file 404错误
  4. Ubuntu 16.04下Caffe-SSD的应用(七)——制作自己的VOC2007数据集
  5. NAB 2019见闻:CAE视频编码与QoE
  6. Portal-Basic Java Web 应用开发框架:应用篇(十四) —— 异步 Action
  7. 目标检测_目标检测: AnchorFree 时代
  8. spring security3(转)
  9. 微信支付封杀虚拟货币交易,亦是重拳无情!
  10. 如何把图片压缩到200k?怎么压缩图片大小kb?
  11. docker容器端口映射
  12. 熵值法、灰色关联分析与层次分析法
  13. css常用单位总结: px / em / rem / vw / vh / vmax / vmin
  14. 1946年第一台公认电子计算机,1946年诞生的世界上公认的第一台电子计算机是()。...
  15. Ansys 15.0 x64 安装
  16. Redis客户端Lettuce深度分析介绍
  17. 【usb】安卓usb网络共享(RNDIS)
  18. ResNet 论文阅读笔记
  19. 初学Linux服务器管理
  20. vue接口多个参数多个组件互动导致数据渲染混乱bug

热门文章

  1. 测试开发 | 这些常用测试平台,你们公司在用的是哪些呢?
  2. 《杭州区块链行业发展报告》披露市场现状
  3. Python爬虫之小试牛刀——使用Python抓取百度街景图像
  4. 20200714学习笔记
  5. 微信小程序接入富文本编辑
  6. c语言--余数正负判断,printf函数占位符
  7. 2023高频经典前端面试题(es6+webpack+http网络+性能优化中篇,含答案)
  8. R语言排序的基本函数
  9. awesome php
  10. 机器学习框架Ray——Actor模型