Rust JSON规范化库json-canon的使用:高效生成标准化JSON数据,支持跨平台一致性验证

Rust JSON规范化库json-canon的使用:高效生成标准化JSON数据,支持跨平台一致性验证

安装

cargo add json-canon

示例

use json_canon::to_string;
use serde_json::json;

let data = json!({
    "from_account": "543 232 625-3",
    "to_account": "321 567 636-4",
    "amount": 500,
    "currency": "USD"
});

println!("{}", to_string(&data)?);
// {"amount":500,"currency":"USD","from_account":"543 232 625-3","to_account":"321 567 636-4"}

完整示例代码

use json_canon::to_string;
use serde_json::{json, Value};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    // 创建JSON数据
    let data: Value = json!({
        "from_account": "543 232 625-3",
        "to_account": "321 567 636-4",
        "amount": 500,
        "currency": "USD",
        "timestamp": "2023-05-01T12:00:00Z",
        "metadata": {
            "location": "New York",
            "ip": "192.168.1.1"
        }
    });

    // 将JSON转换为规范化格式
    let canonical_json = to_string(&data)?;
    
    // 打印规范化后的JSON
    println!("{}", canonical_json);
    // 输出结果将按字段名排序,确保跨平台一致性
    
    Ok(())
}

注意事项

与JavaScript实现不同,serde_jsonf64::NANf64::Infinite反序列化为None,因此如果给定一个包含这些值的Rust结构体,json-canon序列化器目前会输出"null"

性能

基准测试显示该库性能优秀:

from_elem/basic/[{"_id":"59ef4a83ee8364808d761beb","about":"Nisi reprehenderit nulla ad officia pari...
                        time:   [28.019 µs 28.032 µs 28.047 µs]
                        thrpt:  [35.654 Kelem/s 35.673 Kelem/s 35.690 Kelem/s]

许可证

Apache License 2.0

相关项目

  • l1h3r/serde_jcs

1 回复

Rust JSON规范化库json-canon使用指南

简介

json-canon是一个Rust库,用于生成规范化的JSON数据,确保JSON数据在不同平台和系统间具有一致的表示形式。这对于数字签名、数据验证和哈希计算等场景特别有用。

主要特性

  • 将JSON数据转换为规范化的字符串形式
  • 支持所有标准JSON数据类型
  • 跨平台一致性保证
  • 高性能处理

安装

在Cargo.toml中添加依赖:

[dependencies]
json-canon = "0.1"

基本使用方法

规范化JSON字符串

use json_canon::{to_string, JsonValue};
use serde_json::json;

fn main() {
    let data = json!({
        "name": "Alice",
        "age": 30,
        "skills": ["Rust", "Python"],
        "address": {
            "street": "123 Main St",
            "city": "New York"
        }
    });

    let canonical_string = to_string(&data).unwrap();
    println!("{}", canonical_string);
}

验证跨平台一致性

use json_canon::{to_string, JsonValue};
use serde_json::json;

fn compare_json_representations() {
    let json1 = json!({"a": 1, "b": 2});
    let json2 = json!({"b": 2, "a": 1});
    
    let canonical1 = to_string(&json1).unwrap();
    let canonical2 = to_string(&json2).unwrap();
    
    assert_eq!(canonical1, canonical2);
    println!("Different JSON structures produce identical canonical forms");
}

高级用法

自定义选项

use json_canon::{CanonicalizeOptions, to_string_with_options};
use serde_json::json;

fn main() {
    let options = CanonicalizeOptions {
        sort_objects: true,
        ..Default::default()
    };
    
    let data = json!({
        "z": 1,
        "a": 2,
        "m": 3
    });
    
    let result = to_string_with_options(&data, &options).unwrap();
    println!("{}", result); // 输出将按字段名排序
}

处理大型JSON数据

use json_canon::{to_string, JsonValue};
use serde_json::{json, Value};
use std::fs;

fn process_large_json_file() -> Result<(), Box<dyn std::error::Error>> {
    let content = fs::read_to_string("large_data.json")?;
    let data: Value = serde_json::from_str(&content)?;
    
    let canonical = to_string(&data)?;
    fs::write("canonical_output.json", canonical)?;
    
    Ok(())
}

注意事项

  1. 规范化过程会重新排序对象字段
  2. 会移除不必要的空格和换行符
  3. 浮点数会以规范形式表示
  4. Unicode字符会进行规范化处理

性能建议

对于大型JSON处理:

  • 考虑使用流式处理API(如果库支持)
  • 在可能的情况下复用JsonValue实例
  • 对于频繁操作,考虑使用缓冲写入器

这个库特别适合需要确保JSON数据在不同系统间完全一致的场景,如区块链应用、数字签名验证或分布式系统通信。

完整示例

下面是一个完整的示例,展示了如何使用json-canon进行JSON规范化处理:

use json_canon::{to_string, to_string_with_options, CanonicalizeOptions};
use serde_json::json;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    // 示例1:基本用法
    let user_data = json!({
        "id": 12345,
        "name": "Bob",
        "roles": ["admin", "user"],
        "metadata": {
            "created_at": "2023-01-01",
            "updated_at": "2023-05-15"
        }
    });
    
    let canonical_user = to_string(&user_data)?;
    println!("规范化用户数据:\n{}", canonical_user);
    
    // 示例2:验证不同结构的JSON会产生相同的规范化形式
    let json_v1 = json!({"x": 1, "y": 2});
    let json_v2 = json!({"y": 2, "x": 1});
    
    let canonical_v1 = to_string(&json_v1)?;
    let canonical_v2 = to_string(&json_v2)?;
    
    assert_eq!(canonical_v1, canonical_v2);
    println!("验证成功:不同结构的JSON产生了相同的规范化形式");
    
    // 示例3:使用自定义选项
    let options = CanonicalizeOptions {
        sort_objects: true,
        ..Default::default()
    };
    
    let product_data = json!({
        "sku": "P1001",
        "name": "Rust编程书",
        "price": 59.99,
        "categories": ["编程", "技术"],
        "inventory": {
            "warehouse": "CN",
            "stock": 1000
        }
    });
    
    let canonical_product = to_string_with_options(&product_data, &options)?;
    println!("使用自定义选项后的规范化产品数据:\n{}", canonical_product);
    
    Ok(())
}

这个完整示例展示了:

  1. 基本规范化操作
  2. 验证不同JSON结构会产生相同规范化形式
  3. 使用自定义选项进行规范化
  4. 完整的错误处理

您可以根据实际需求调整这些示例代码。

回到顶部