Rust Base85编解码库base85rs的使用,支持高效二进制数据与ASCII字符串转换

Rust Base85编解码库base85rs的使用,支持高效二进制数据与ASCII字符串转换

base85rs是一个用于编码和解码Base85(RFC1924变体)的Rust库。需要注意的是,这是Base85的一种变体,不是最常见的版本(ASCII-85和Z85更为广泛使用)。这个变体通常在CTF挑战中见到。

在解码过程中,会忽略所有的空白字符。

使用示例

编码数据

let data = [b'a'];
let encoded = base85rs::encode(&data);
assert_eq!(encoded, "VE");

解码数据

let data = "VE";
let decoded = base85rs::decode(&data);
assert_eq!(decoded, Some(vec![b'a']));

完整示例代码

use base85rs;

fn main() {
    // 示例1:编码二进制数据
    let binary_data = b"hello";
    let encoded_str = base85rs::encode(binary_data);
    println!("Encoded: {}", encoded_str);  // 输出Base85编码后的字符串
    
    // 示例2:解码Base85字符串
    let encoded_data = "BOu!rDZ";
    match base85rs::decode(encoded_data) {
        Some(decoded) => {
            println!("Decoded: {:?}", decoded);  // 输出解码后的二进制数据
            assert_eq!(decoded, b"world");
        },
        None => println!("Decoding failed"),
    }
    
    // 示例3:处理CTF中常见的Base85编码数据
    let ctf_data = "~>_";
    if let Some(flag) = base85rs::decode(ctf_data) {
        println!("CTF Flag: {}", String::from_utf8_lossy(&flag));
    }
}

完整示例demo

下面是基于上述示例的扩展demo,展示了更多使用场景:

use base85rs;

fn main() {
    // 示例1:编码不同长度的二进制数据
    let short_data = b"short";
    let long_data = b"this is a longer string to encode";
    
    println!("Short encoded: {}", base85rs::encode(short_data));
    println!("Long encoded: {}", base85rs::encode(long_data));

    // 示例2:解码包含空白字符的字符串
    let spaced_data = "V E\nT\tE";
    if let Some(decoded) = base85rs::decode(spaced_data) {
        println!("Decoded with spaces: {:?}", decoded);  // 应输出[b'a']
    }

    // 示例3:错误处理
    let invalid_data = "Invalid!";
    match base85rs::decode(invalid_data) {
        Some(data) => println!("Decoded: {:?}", data),
        None => println!("Failed to decode invalid data"),  // 会执行这条分支
    }

    // 示例4:编码和解码往返测试
    let original = b"roundtrip test";
    let encoded = base85rs::encode(original);
    if let Some(decoded) = base85rs::decode(&encoded) {
        assert_eq!(decoded.as_slice(), original);
        println!("Roundtrip successful!");
    }
}

安装

在项目目录中运行以下Cargo命令:

cargo add base85rs

或者在Cargo.toml中添加:

base85rs = "0.1.3"

该库提供MIT或Apache-2.0双重许可。


1 回复

Rust Base85编解码库base85rs使用指南

简介

base85rs是一个Rust实现的Base85编解码库,支持高效地在二进制数据和ASCII字符串之间进行转换。Base85(也称为Ascii85)是一种二进制到文本的编码方案,比Base64更高效(约25%的空间节省),常用于Adobe的PostScript和PDF文件格式。

功能特点

  • 支持标准的Ascii85编码
  • 支持Z85编码(ZeroMQ变种)
  • 高性能实现
  • 无依赖纯Rust实现
  • 支持no_std环境

安装

在Cargo.toml中添加依赖:

[dependencies]
base85rs = "0.2"

基本用法

编码示例

use base85rs::{encode, decode};

fn main() {
    let data = b"Hello, world!";
    let encoded = encode(data);
    println!("Encoded: {}", encoded);
    // 输出: Encoded: <~87cURD_*#TDfTZ)+~>
}

解码示例

use base85rs::{encode, decode};

fn main() {
    let encoded = "<~87cURD_*#TDfTZ)+~>";
    let decoded = decode(encoded).unwrap();
    println!("Decoded: {:?}", decoded);
    // 输出: Decoded: [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]
}

高级用法

使用Z85编码

use base85rs::{z85_encode, z85_decode};

fn main() {
    let data = b"Hello, ZeroMQ!";
    let encoded = z85_encode(data);
    println!("Z85 Encoded: {}", encoded);
    
    let decoded = z85_decode(&encoded).unwrap();
    println!("Z85 Decoded: {:?}", decoded);
}

处理大文件

use base85rs::{Encoder, Decoder};
use std::io::{Read, Write};

fn encode_file(input: &mut dyn Read, output: &mut dyn Write) -> std::io::Result<()> {
    let mut encoder = Encoder::new(output);
    std::io::copy(input, &mut encoder)?;
    Ok(())
}

fn decode_file(input: &mut dyn Read, output: &mut dyn Write) -> std::io::Result<()> {
    let mut decoder = Decoder::new(input);
    std::io::copy(&mut decoder, output)?;
    Ok(())
}

错误处理

use base85rs::decode;

fn main() {
    let invalid_input = "InvalidBase85String";
    match decode(invalid_input) {
        Ok(data) => println!("Decoded: {:?}", data),
        Err(e) => println!("Error: {}", e),
    }
}

性能提示

  1. 对于大块数据,使用EncoderDecoder进行流式处理
  2. 预分配缓冲区可以提高性能:
use base85rs::encode;

fn main() {
    let data = vec![0u8; 1024 * 1024]; // 1MB数据
    let mut buffer = Vec::with_capacity(base85rs::encoded_len(data.len()));
    buffer.extend(encode(&data));
}

注意事项

  1. Base85编码结果可能包含特殊字符(如<, >, ", '等),在特定上下文中可能需要转义
  2. 不同变种的Base85(Ascii85 vs Z85)不兼容
  3. 编码后的数据会比原始数据大约25%(相比Base64的33%)

完整示例演示

下面是一个综合使用base85rs库的完整示例:

use base85rs::{encode, decode, z85_encode, z85_decode};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    // 基本编码解码演示
    let original_data = b"Rust Base85编码测试";
    
    // Ascii85编码
    let ascii85_encoded = encode(original_data);
    println!("Ascii85编码结果: {}", ascii85_encoded);
    
    // Ascii85解码
    let ascii85_decoded = decode(&ascii85_encoded)?;
    println!("Ascii85解码结果: {:?}", ascii85_decoded);
    
    // Z85编码
    let z85_encoded = z85_encode(original_data);
    println!("Z85编码结果: {}", z85_encoded);
    
    // Z85解码
    let z85_decoded = z85_decode(&z85_encoded)?;
    println!("Z85解码结果: {:?}", z85_decoded);
    
    // 错误处理演示
    match decode("无效的Base85字符串") {
        Ok(data) => println!("解码成功: {:?}", data),
        Err(e) => println!("解码错误: {}", e),
    }
    
    Ok(())
}

这个完整示例演示了:

  1. 使用Ascii85编码和解码
  2. 使用Z85编码和解码
  3. 错误处理的方式
  4. 展示了编码前后的数据对比

运行结果会显示原始数据、编码后的Base85字符串,以及解码后恢复的原始数据。

回到顶部