Rust Base85编解码库base85的使用,支持高效二进制数据与ASCII字符串转换
Rust Base85编解码库base85的使用,支持高效二进制数据与ASCII字符串转换
base85是一个用于Base85编码的Rust库,遵循RFC1924规范,采用Mozilla Public License 2.0许可证发布。
描述
Base85编码有多种变体。最流行的变体通常被称为ascii85,以在Adobe产品中使用而闻名。本库实现的不是该算法。
RFC1924中实现的变体最初用于编码IPv6地址。它与其他版本使用相同的概念,但使用的字符集对嵌入源代码更友好,无需转义。在解码过程中会忽略ASCII空白字符(\n、\r、\t、空格)。Base85编码字符串比原始二进制数据大25%,比更常见的base64算法(33%)更高效。这种编码与JSON配合非常好,开销更低且不需要字符转义。
使用方法
虽然这是我第一个真正的Rust代码,但代码经过了充分测试,API也很简单:
encode()
将字节切片转换为字符串decode()
将字符串引用转换为字节向量(u8)
这两个调用都在RAM中工作,因此处理大文件可能不是一个好主意。
安装
在项目目录中运行以下Cargo命令:
cargo add base85
或者在Cargo.toml中添加以下行:
base85 = "2.0.0"
完整示例代码
use base85;
fn main() {
// 原始二进制数据
let binary_data = b"Hello, Base85!";
// 编码为Base85字符串
let encoded = base85::encode(binary_data);
println!("Encoded: {}", encoded);
// 解码回二进制数据
match base85::decode(&encoded) {
Ok(decoded) => {
println!("Decoded: {:?}", decoded);
assert_eq!(binary_data.as_ref(), decoded.as_slice());
},
Err(e) => println!("Decoding error: {}", e),
}
}
扩展示例代码
use base85;
use std::fs;
fn main() {
// 示例1:编码解码短字符串
let short_str = b"Rust Base85 encoding";
let encoded_short = base85::encode(short_str);
println!("Short string encoded: {}", encoded_short);
if let Ok(decoded_short) = base85::decode(&encoded_short) {
println!("Short string decoded: {:?}", String::from_utf8_lossy(&decoded_short));
}
// 示例2:处理文件内容
if let Ok(file_data) = fs::read("example.bin") {
// 编码文件内容
let encoded_file = base85::encode(&file_data);
println!("File encoded length: {}", encoded_file.len());
// 解码文件内容
match base85::decode(&encoded_file) {
Ok(decoded_file) => {
println!("File decoded length: {}", decoded_file.len());
assert_eq!(file_data, decoded_file);
},
Err(e) => println!("File decoding error: {}", e),
}
}
// 示例3:处理包含空白字符的编码字符串
let encoded_with_whitespace = "Hello\nWorld\tBase85";
match base85::decode(encoded_with_whitespace) {
Ok(decoded) => {
println!("Decoded with whitespace: {:?}", String::from_utf8_lossy(&decoded));
},
Err(e) => println!("Error decoding with whitespace: {}", e),
}
}
贡献
我虽然编程有一段时间了,但在Rust方面还是个初学者。欢迎提出建议和贡献。虽然出于历史原因在GitHub上有一个镜像仓库,但此crate的官方仓库在GitLab。非常欢迎将问题和PR提交到该位置。
许可证
MPL-2.0-no-copyleft-exception
Rust Base85编解码库base85使用指南
介绍
base85
是一个Rust实现的Base85(Ascii85)编解码库,用于在二进制数据和ASCII字符串之间进行高效转换。Base85编码比Base64更高效,能将4字节二进制数据编码为5个ASCII字符。
特性
- 支持标准Ascii85编码(RFC 1924)
- 支持Z85编码(ZeroMQ规范)
- 高性能实现
- 无依赖纯Rust实现
使用方法
首先在Cargo.toml
中添加依赖:
[dependencies]
base85 = "0.3"
基本编码解码
use base85::{Ascii85, Codec};
fn main() {
// 原始数据
let data = b"hello world";
// 编码
let encoded = Ascii85.encode(data);
println!("Encoded: {}", encoded);
// 输出: Encoded: <~87cURDZ*#TDfTZ)~>
// 解码
let decoded = Ascii85.decode(&encoded).unwrap();
println!("Decoded: {:?}", decoded);
// 输出: Decoded: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
}
使用Z85编码
use base85::{Z85, Codec};
fn main() {
let data = b"Rust is awesome!";
// Z85编码
let encoded = Z85.encode(data);
println!("Z85 encoded: {}", encoded);
// Z85解码
let decoded = Z85.decode(&encoded).unwrap();
assert_eq!(decoded, data);
}
处理大文件
use base85::{Ascii85, Codec};
use std::io::{Read, Write};
fn encode_file(input_path: &str, output_path: &str) -> std::io::Result<()> {
let mut input_file = std::fs::File::open(input_path)?;
let mut output_file = std::fs::File::create(output_path)?;
// 分块读取和编码
let mut buffer = vec![0u8; 4096];
loop {
let bytes_read = input_file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
let encoded = Ascii85.encode(&buffer[..bytes_read]);
writeln!(output_file, "{}", encoded)?;
}
Ok(())
}
自定义配置
use base85::{Config, Codec};
fn main() {
let custom_config = Config::new()
.with_padding(false) // 不使用填充
.with_delimiters(None, None); // 不使用分隔符
let data = b"custom configuration";
let encoded = custom_config.encode(data);
println!("Custom encoded: {}", encoded);
}
性能提示
- 对于大型数据,考虑使用分块处理
- 如果不需要分隔符,可以禁用它们以提高性能
- Z85通常比Ascii85有更好的性能
错误处理
解码时可能会出错,应该正确处理错误:
use base85::Ascii85;
fn safe_decode(encoded: &str) -> Result<Vec<u8>, String> {
Ascii85.decode(encoded)
.map_err(|e| format!("Decoding failed: {}", e))
}
完整示例
下面是一个完整的Base85编解码示例,包含文件处理、自定义配置和错误处理:
use base85::{Ascii85, Z85, Config, Codec};
use std::fs;
use std::io::{self, Read, Write};
fn main() -> io::Result<()> {
// 1. 基本编码解码演示
let data = b"Rust Base85 demo";
println!("原始数据: {:?}", data);
// Ascii85编码
let ascii85_encoded = Ascii85.encode(data);
println!("Ascii85编码: {}", ascii85_encoded);
// Ascii85解码
let ascii85_decoded = Ascii85.decode(&ascii85_encoded).unwrap();
println!("Ascii85解码: {:?}", ascii85_decoded);
// Z85编码
let z85_encoded = Z85.encode(data);
println!("Z85编码: {}", z85_encoded);
// Z85解码
let z85_decoded = Z85.decode(&z85_encoded).unwrap();
println!("Z85解码: {:?}", z85_decoded);
// 2. 文件编码演示
// 创建测试文件
fs::write("test.txt", "This is a test file for Base85 encoding")?;
// 编码文件
encode_file_to_base85("test.txt", "encoded.txt")?;
println!("文件编码完成");
// 3. 自定义配置演示
let custom_config = Config::new()
.with_padding(false)
.with_delimiters(None, None);
let custom_encoded = custom_config.encode(data);
println!("自定义配置编码: {}", custom_encoded);
// 4. 错误处理演示
match safe_decode("invalid base85 string") {
Ok(decoded) => println!("解码成功: {:?}", decoded),
Err(e) => println!("解码错误: {}", e),
}
Ok(())
}
/// 将文件内容编码为Base85格式
fn encode_file_to_base85(input_path: &str, output_path: &str) -> io::Result<()> {
let mut input_file = fs::File::open(input_path)?;
let mut output_file = fs::File::create(output_path)?;
let mut buffer = vec![0u8; 4096];
loop {
let bytes_read = input_file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
let encoded = Ascii85.encode(&buffer[..bytes_read]);
writeln!(output_file, "{}", encoded)?;
}
Ok(())
}
/// 安全解码Base85字符串
fn safe_decode(encoded: &str) -> Result<Vec<u8>, String> {
Ascii85.decode(encoded)
.map_err(|e| format!("解码失败: {}", e))
}
这个示例展示了:
- 基本的Ascii85和Z85编解码操作
- 文件编码处理
- 自定义配置使用
- 错误处理机制
要运行这个示例,请确保在Cargo.toml中添加了base85依赖。