#bittorrent #encoder #codec #torrent

bin+lib bencode-encoder

Bencode 编码器 for Rust

3 个版本

0.1.2 2023年8月20日
0.1.1 2023年8月20日
0.1.0 2023年2月22日

#863 in 编码

MIT 许可证

64KB
1.5K SLoC

Bencode (Bee-encode)

Rust 的 bencode 编码实现。Bencode 是由 BitTorrent 点对点文件共享系统用于存储和传输结构化数据的编码方式。Bencoding 最常用于 torrent 文件,因此它是 BitTorrent 规范的一部分。这些元数据文件是简单的 bencoded 字典。

Bencoding 简单且(因为数字以十进制文本形式编码)不受字节序的影响,这对于像 BitTorrent 这样的跨平台应用程序非常重要。它也相当灵活,只要应用程序忽略意外的字典键,就可以添加新的键而不产生不兼容性。

安装

您可以使用以下命令在 Rust 项目中安装 bencode_encoder crate:

$cargo add bencode-encoder

数据类型

Bencode 规范支持 4 种数据类型

  • 字节字符串(编码为 length:content,例如 4:rust
  • 整数(编码为 inumbere,例如 i20e
  • 列表(编码为 l<contents>e,例如 l4:rusti20ee
  • 带有排序字符串键的字典(编码为 d<contents>e,例如 d1:ki2023ee

示例用法(从 .torrent 文件解码并存储为 .json 文件)

use bencode_encoder::Decoder;


fn main() {
    let input_file = std::env::args().nth(1)
            .expect("Usage: decode <input_file> <output_file>");
    let output_file = std::env::args().nth(2)
            .expect("Usage: decode <input_file> <output_file>");

    match Decoder::decode_from(input_file) {
        Err(err) => println!("{}", err.to_string()),
        Ok(t) => {
            match t.save_to_json(output_file) {
                Err(err) => println!("{}", err.to_string()),
                Ok(_) => println!("Decoded bencode saved to .json file"),
            }
        },
    }
}

示例用法(从 .json 文件读取并编码到 .torrent 文件)

use bencode_encoder::{Encoder, Type};


fn main() {
    let input_file = std::env::args().nth(1)
            .expect("Usage: encode <input_file> <output_file>");
    let output_file = std::env::args().nth(2)
            .expect("Usage: encode <input_file> <output_file>");

    match Type::load_from_json(input_file) {
        Err(err) => println!("{}", err.to_string()),
        Ok(t) => {
            match Encoder::encode_to(&t, output_file) {
                Err(err) => println!("{}", err.to_string()),
                Ok(_) => println!("Encoded bencode saved to binary file"),
            }
        },
    }
}

BNF

以下显示了用于解析的 BNF(点击 这里 了解更多)。此 crate 根据以下 BNF 实现了简单的解析器。

<BE>    ::= <DICT> | <LIST> | <INT> | <STR>

<DICT>  ::= "d" 1 * (<STR> <BE>) "e"
<LIST>  ::= "l" 1 * <BE>         "e"
<INT>   ::= "i"     <SNUM>       "e"
<STR>   ::= <NUM> ":" n * <CHAR>; where n equals the <NUM>

<SNUM>  ::= "-" <NUM> / <NUM>
<NUM>   ::= 1 * <DIGIT>
<CHAR>  ::= %
<DIGIT> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

测试

要运行测试,请使用

$cargo test

依赖项

~0.8–1.7MB
~36K SLoC