`

bencode解码实现

阅读更多
字符串:

字符串被如此编码:<字符串长度>:字符串正文.这种表示法没有任何的分界符.
例子:如"8:announce"指"announce".

整数:
整数被如此编码:<i>整数值<e>.可以为负数,如'i-3e'
例子:'i3e' 指 3.

列表:
列表是如此被表示的:<l>Bencode Value<e>,
列表可以用来表示多个对象.
列表内容可以包括字符串,整数,字典,甚至列表本身.
例子:'l4:spam4:eggse' 指 [ "spam", eggs" ]

字典:
字典是一个一对一的映射.它表示了一个主键(必须为字符串)和一个数据项(可以为任何Bencode值)的关系.字典可以用来表示一个对象的多种属性.
字典是如此被编码:<d><bencoded string><bencoded element><e>
注意:字典必须根据主键预排序.
package com.norkts.torrents;

import java.io.*;
import java.nio.ByteBuffer;
import java.util.*;

/**
 * bencode解码实现
 * @author norkts<norkts@gmail.com>
 * @date 2017-06-21
 * @version 1.0
 */
public class BencodeDecoder {

    public static Object decode(byte[] data){
        ByteBuffer buffer = ByteBuffer.wrap(data);

        return decode(buffer);
    }

    public static Object decode(ByteBuffer buffer){

        Stack<Object> endStack = new Stack<Object>();

        while (buffer.hasRemaining()){

            byte ch = buffer.get();

            if(ch >= '0' & ch <= '9'){
                buffer.position(buffer.position() - 1);
                //string
                byte[] lenByte = readUntil(buffer, ':');
                int len = Integer.parseInt(new String(lenByte));

                lenByte = new byte[len];

                buffer.get(lenByte);

                String str = new String(lenByte);
                if(endStack.empty()){
                    endStack.push(new LinkedList<Object>());
                }

                setStackVal(endStack, str);


                //继续执行下一次
                continue;
            }

            if(ch == 'i'){
                //字符串处理
                byte[] temp = readUntil(buffer, 'e');

                Long val = Long.parseLong(new String(temp));

                if(endStack.empty()){
                    endStack.push(new LinkedList<Object>());
                }

                setStackVal(endStack, val);

                continue;
            }

            if(ch == 'l'){
                //列表处理
                endStack.push(new LinkedList<Object>());
                continue;
            }

            if(ch == 'd'){
                //字典类型开始解码
                endStack.push(new LinkedHashMap<Object, Object>());
                continue;
            }

            if(ch == 'e'){
                Object last = endStack.pop();
                if(endStack.empty()){
                    return last;
                }

                setStackVal(endStack, last);
            }


        }

        return endStack.empty() ? null : endStack.pop();
    }

    private static byte[] readUntil(ByteBuffer buff, char end){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while (true){
            byte ch = buff.get();
            if(ch == end){
                break;
            }

            baos.write(ch);
        }

        return baos.toByteArray();
    }

    private static void setStackVal(Stack<Object> stack, Object val){
        Object prev = stack.peek();
        if(prev instanceof List){
            ((List)prev).add(val);
        }else if(prev instanceof Map){
            Pair<Object, Object> entry = new Pair<Object, Object>(val, null);
            stack.push(entry);
        }else if(prev instanceof Pair){
            Pair<Object, Object> entry = (Pair<Object, Object>)stack.pop();
            entry.setVal(val);

            prev = stack.peek();
            ((Map<Object, Object>)prev).put(entry.getKey(), entry.getVal());
        }
    }

    static class Pair<K,V>{
        private K key;
        private V val;

        public Pair(K k, V v){
            this.key = k;
            this.val = v;
        }

        public K getKey() {
            return key;
        }

        public void setKey(K key) {
            this.key = key;
        }

        public V getVal() {
            return val;
        }

        public void setVal(V val) {
            this.val = val;
        }
    }

    public static void main(String[] argv){


/*        Object obj = BencodeDecoder.decode("l:3:abci45678el:3:xxxi123ed3:key3:val4:name5:zhangeee".getBytes());
        System.out.println(obj);

        obj = BencodeDecoder.decode("d3:key3:val4:name5:zhang3:mapd3:key3:vali123e4:xxxxee".getBytes());
        System.out.println(obj);*/

        try {
            File f = new File("Q:\\study\\torrents\\0000405710f78d75c5d1dd9cc69ffdd7d1561bb1.torrent");
            FileInputStream inputStream = new FileInputStream(f);
            ByteBuffer buff = ByteBuffer.allocate((int)f.length());

            inputStream.getChannel().read(buff);
            inputStream.close();

            buff.flip();
            Object o = BencodeDecoder.decode(buff);

            System.out.println(o);

            System.out.println((((Map<String, Object>)((Map<String, Object>)o).get("info"))).keySet());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
0
1
分享到:
评论

相关推荐

    rust-bencode:Rust 语言中的 Bencode 解析器实现

    **锈本码 (Rust-Bencode):Rust 语言中的 Bencode 解析器实现** 在数字时代,数据编码格式是传输和存储信息的关键部分。Bencode 是 BitTorrent 协议中广泛使用的一种简单且高效的编码方式,用于表示字典、列表、...

    bencode.rar

    虽然名字暗示这是一个C++文件,但根据上下文,它更可能是C#源码文件,可能包含了实现`bencode`解码逻辑的函数和类。在C#中,`.cpp`后缀并不常见,通常用`.cs`表示C#源文件。这个文件可能包含了`BencodeDecoder`类,...

    bencode:Go中的Bencode实现

    本码 Go中的Bencode实现安装$ go get github.com/marksamman/bencode用法编码bencode.Encode使用map [string] interface {}作为参数,并返回一个字节数组。 例子: package mainimport ("fmt""github....

    一种针对Bencode编码实现的BitTorrent系统攻击方法

    最初的Bittorrent系统是用python实现的,其中的Bencode编解码采用了递归的方式,后续的很多BT客户端实现都直接拷贝了这种方式。这就为针对Bencode编码实现的攻击提供了可能。首先构造了有一定递归深度的torrent文件...

    Laravel开发-bencode

    - 使用示例代码展示如何在Laravel中实现Bencode编码和解码,以及如何在控制器、模型或服务中集成这些功能。 通过以上介绍,我们可以看出“Laravel开发-bencode”是关于在Laravel框架中使用Bencode进行数据序列化和...

    rust-bencode-源码.rar

    这些函数通过递归处理各种Bencode元素,实现了解码和编码的全过程。 3. **错误处理**:Rust的错误处理机制在rust-bencode库中得到了充分的体现。通过返回`Result`类型,解析和编码过程中的任何错误都能被及时捕获并...

    Bencode:适用于Java的Bencode库

    这是Bencode for Java的实现。 Bencode用于DHT,Torrent和Google DataServer。 它是一种轻量级的快速数据序列化。 基准测试 这里是与其他主要数据序列化方法相比该库的一些示例。 序列化/编码 方法 时间在米尔斯 ...

    elixir_bencode:在 Elixir 中实现的 Bencode

    Bencode 解码器/编码器使用 Elixir 数据结构。 安装 将其添加到您的mix.exs依赖项中: defp deps do [{ :elixir_bencode , " ~&gt; 1.0.0 " }] end 例子 ## Encode strings (with thrown exceptions) Bencode . ...

    bencode:Clojure的netstring和bencode实现

    描述中的“bencode:Clojure的netstring和bencode实现”进一步确认了这个项目是用Clojure语言实现的bencode和netstring的编码和解码功能。这可能包括库或工具,使得Clojure开发者能够方便地在他们的项目中处理这两种...

    bencode_online:浏览器中的Bencode和bdecode

    3. **JavaScript**:作为项目的开发语言,JavaScript是Web开发中不可或缺的一部分,它被用来实现这个在线工具的功能,包括接收用户输入、处理Bencode编码和解码逻辑,并在前端展示结果。 4. **前端构建工具**:项目...

    bencode-SerDe:Java 中的 Bencode 序列化和反序列化

    - **源代码**:`BEncode.java`是实现Bencode序列化和反序列化的核心类,它包含了处理不同类型数据的方法。 - **测试代码**:`BEncodeTest.java`包含了对`BEncode`类的测试用例,用来验证其功能的正确性。 - **构建...

    QBencode:Qt 中的 Bencode 读写支持

    通过这个库,你可以轻松地将 C++ 数据结构编码为 Bencode 格式,或将接收到的 Bencode 数据解码回 C++ 对象。这对于编写与 BitTorrent 协议相关的应用,或者需要与使用 Bencode 格式的数据源交互的任何其他应用来说...

    nim-bencode:Nim的Bencode库

    通过阅读库的文档或者源代码,你可以学习如何调用库的函数进行Bencode数据的编码和解码操作。 例如,一个简单的使用示例可能如下: ```nim import bencode var data = {"key1": "value1", "key2": 42} var ...

    Bencoder:Python 编码器和解码器

    1. `bencoder.py`:库的核心实现,包含了`bencode`和`bdecode`等函数的代码。 2. `tests/`:测试目录,包含单元测试用例,用于验证库的功能是否正常工作。 3. `README.md`:项目说明文件,详细介绍了库的安装、使用...

    bencode:Prolog 的编码

    在"bencode-master"这个压缩包文件中,可能包含了实现bencode编码和解码功能的Prolog源代码。通常,这样的项目会包含若干个Prolog文件,每个文件对应一部分功能,如处理整数、字符串、列表或字典的编码和解码。...

    grizzly-portunif-2.3-rc3.zip

    然而,描述中并未直接提到Grizzly或PortUnif,而是提到了“bencode.zip”和“bencode解码器与torrent实用程序”,这暗示了我们关注的焦点可能转移到了BitTorrent协议和bencoding技术上。 “bencode”是一种编码方式...

    bt客户端源码,用vc实现

    2. **Bencode解码和编码**:BitTorrent的元数据文件(.torrent)使用Bencode编码,客户端需要解析这个文件来获取文件信息和Tracker服务器地址。同样,客户端也需要将状态更新编码成Bencode格式发送回Tracker。 3. *...

    BT种子解析器(C++源代码).rar

    你需要实现一个bencode解码器来提取info部分的信息。 4. **计算pieces哈希**:从info部分提取文件的哈希列表,这可以用来验证下载的数据是否正确。 5. **连接Tracker**:使用announce信息,通过HTTP或UDP与Tracker...

    beradio:Arduino和Python的BERadio规范和实现。 通过无线电链路以Bencode格式传输数据,解码并发布到MQTT

    关于BERadio是用于在受限无线电链路环境中进行有效通信的编码规范和实现。 它被构想并用于内的无线通信。 它与 (一个用于构建灵活的遥测解决方案的多通道,多协议数据采集和图形化工具包)一起,为网关侧的提供了...

Global site tag (gtag.js) - Google Analytics