Sign in

    moonrecoder

    Bounded GF256 packet innovation, decoding and incomplete-relay recoding in pure MoonBit

    rlnc
    network-coding
    recoding
    gf256
    packet
    Download zip
    Version
    0.1.0
    License
    MIT
    Last updated
    8 hours ago
    Downloads
    2

    #MoonRecoder

    纯 MoonBit 的有界 GF(256) 随机线性网络编码内核:增量创新性判断、精确恢复、未解码中继重编码,以及可诊断的包追踪重放。

    适用于在 MoonBit 中实现丢包实验、遥测网关、仿真中继或离线抓包诊断。它是可嵌入的同步库,不包含网络传输、重传调度或加密认证。MIT;模块 ZJH-666-ZJH/moonrecoder@0.1.0。

    #安装

    使用支持 moon.mod / moon.pkg 的 MoonBit 稳定工具链。在自己的模块中:

    moon add ZJH-666-ZJH/moonrecoder@0.1.0

    在消费者 moon.pkg 中加入:

    import {
    "ZJH-666-ZJH/moonrecoder" @r,
    }

    #最小恢复流程

    下面的逻辑可以放在测试块中;构造与接纳可能抛出 CodeError。完整可运行程序见 examples/。

    let input = @r.Symbols::from_bytes(b"hello")
    let encoder = @r.Encoder::new(7, input, 2)
    let decoder = @r.Decoder::new(encoder.generation())
    ignore(decoder.admit(encoder.systematic(0, 0)))
    ignore(decoder.admit(encoder.systematic(2, 2)))
    let hint = @r.feedback_from_wire(decoder.feedback().to_wire())
    ignore(decoder.admit_batch(encoder.repair(hint, 10)))
    assert_true(decoder.recover().equal(input))

    #三个完整工作流

    下游用户输入与处理可核验结果命令
    遥测网关 / 丢包实验开发者五个系统包中丢两个、重复一个,经反馈请求缺失主元修复两个修复包恢复原始字节,重复计数为 1moon run examples/telemetry
    多跳仿真 / 中继组件开发者中继仅收到三个源符号中的两个,在秩不足时混合当前基下游收到两个独立混合包和另一个源包后恢复;中继始终秩 2moon run examples/relay
    测试设施 / 离线诊断作者非法 hex、重复帧、两代交错流和七字节网络切片生成拒绝事件、不污染秩,分别恢复两代并释放保留额度moon run examples/trace

    可在命令中加 --target wasm-gc、wasm、js 或 native。运行 native 需要相应 C 编译器;本地 Windows 未安装 C 编译器,native 的执行验证由 Ubuntu CI 承担。

    #主要接口

    • Symbols:0..255 验证、分离可变数组、Bytes/hex 适配、向量乘加。
    • FieldMatrix:有界批量秩、乘法和逆;Basis:增广 RREF、部分已知符号和矛盾检测。
    • Encoder:系统包、显式系数包、确定性系数流、缺失主元反馈修复。
    • Decoder:创新 / 依赖判定、秩 / 额度 / JSON 报告、恢复、fork、原子批量接纳。
    • Relay:基序混合、确定性系数流混合、独立基包导出,不要求先恢复源。
    • Packet / Feedback:自定义 MRC1 / MRF1 格式,长度、形状、域边界和 CRC 校验。
    • FrameReader:网络分片组帧;整次 feed 失败回滚,不做字节流重同步。
    • SessionPool:多代分派、字段单元保留预算、显式回收。
    • Replay:hex / wire 输入转结构化事件;坏包记录为 rejected,而非使整个重放退出。

    完整公开签名见生成的 pkg.generated.mbti;架构与不变量、逐字节格式、安全边界。

    #约束,不可误用为保证

    GF(256) 多项式为 0x11d;每代 1..64 个源符号,每符号 1..4096 字节,总源容量不超过 262144 字节。最后符号零填充;空输入无代。generation ID / sequence 使用非负有符号 31 位整数。

    随机包不保证任意 k 包可恢复;依赖包不增加秩。序号仅为元数据,不用于去重和防重放。同序号不同独立方程可以增加秩,换序号的重复方程仍然依赖。重编码只能重新分布已有信息,不能增加中继的秩。

    CoefficientStream 使用可复现 xorshift32;全零向量替换为 e0,分布并不均匀,也不具密码学安全性。流额度按生成的系数字节数计算,而非包数。CRC32 仅检测意外损坏,攻击者可重算它。欠定的污染包可能仍可接纳;应用必须在接纳前实现认证。

    这不是 Reed–Solomon、RaptorQ 或 RFC 8681 的互操作实现。没有 MDS 保证、socket、自动重传、持久化会话、抗恶意编码或常数时间实现。

    #验证

    moon info moon fmt moon fmt --check moon check --deny-warn --target wasm-gc moon build --deny-warn --target wasm-gc moon test --deny-warn --target wasm-gc moon run examples/telemetry --target wasm-gc --deny-warn moon run examples/relay --target wasm-gc --deny-warn moon run examples/trace --target wasm-gc --deny-warn

    把目标替换为 wasm / js / native 可复现 CI 流程。43 个测试包含所有 65536 对域乘法与独立多项式长除法 oracle 的比较、增量/批量秩一致性、255 组中继权重、全部单切点组帧、最大帧、矛盾与原子回滚。没有发布吞吐量或覆盖率保证。

    CI 使用干净 Ubuntu runner 执行四后端检查、构建、测试和三个示例。实际交付证据见 工程审计。

    #来源与参与

    这是原创工程实现,不是第三方库移植。运行时仅依赖 MoonBit 标准库;没有复制相邻项目源码。参考/许可证边界、AI 使用说明、变更记录、有界查重证据。

    报告问题时请提供目标后端、工具链版本、维度和最小可公开的包 trace;不要提交生产数据、认证材料或私密抓包。参赛申报材料不属于本仓库。

    CodeError

    pub(all) suberror CodeError {
    Invalid(String)
    Shape(String)
    Limit(String)
    Inconsistent
    Incomplete(Int)
    Corrupt(String)
    Truncated
    }

    Admission

    pub enum Admission {
    Innovative(Int, Int)
    Dependent
    }

    Basis

    pub struct Basis {
    columns : Int
    width : Int
    rows : Array[Equation?]
    rank_value : Int
    }

    Basis::admit

    fn Basis::admit(self : Basis, equation : Equation) -> Admission raise CodeError

    Basis::deficit

    fn Basis::deficit(self : Basis) -> Int

    Basis::equations

    fn Basis::equations(self : Basis) -> Array[Equation]

    Basis::known

    fn Basis::known(self : Basis) -> Array[(Int, Symbols)]

    Basis::new

    fn Basis::new(columns : Int, width : Int) -> Basis raise CodeError

    Basis::pivots

    fn Basis::pivots(self : Basis) -> Array[Int]

    Basis::rank

    fn Basis::rank(self : Basis) -> Int

    Basis::recover

    fn Basis::recover(self : Basis) -> Array[Symbols] raise CodeError

    CoefficientStream

    pub struct CoefficientStream {
    state : UInt
    draw_count : Int
    draw_limit : Int
    }

    CoefficientStream::draw

    fn CoefficientStream::draw(self : CoefficientStream, count : Int) -> Symbols raise CodeError

    CoefficientStream::draws

    fn CoefficientStream::draws(self : CoefficientStream) -> Int

    CoefficientStream::new

    fn CoefficientStream::new(seed : UInt, max_draws? : Int) -> CoefficientStream raise CodeError

    CoefficientStream::remaining

    fn CoefficientStream::remaining(self : CoefficientStream) -> Int

    Crc32

    pub struct Crc32 {
    accumulator : UInt
    }

    Crc32::new

    fn Crc32::new() -> Crc32

    Crc32::update

    fn Crc32::update(self : Crc32, bytes : Symbols) -> Unit

    Crc32::value

    fn Crc32::value(self : Crc32) -> UInt

    DecodeReport

    pub(all) struct DecodeReport {
    generation_id : Int
    source_count : Int
    rank : Int
    deficit : Int
    admitted : Int
    dependent : Int
    known : Int
    pivots : Array[Int]
    }

    DecodeReport::to_json

    fn DecodeReport::to_json(self : DecodeReport) -> String

    Decoder

    pub struct Decoder {
    generation_value : Generation
    basis : Basis
    packet_limit : Int
    admitted_count : Int
    dependent_count : Int
    }

    Decoder::admit

    fn Decoder::admit(self : Decoder, packet : Packet) -> Admission raise CodeError

    Decoder::admit_batch

    fn Decoder::admit_batch(self : Decoder, packets : Array[Packet]) -> Array[Admission] raise CodeError

    Decoder::admit_wire_batch

    fn Decoder::admit_wire_batch(self : Decoder, frames : Array[Symbols]) -> Array[Admission] raise CodeError

    Decoder::admitted

    fn Decoder::admitted(self : Decoder) -> Int

    Decoder::basis_equations

    fn Decoder::basis_equations(self : Decoder) -> Array[Equation]

    Decoder::deficit

    fn Decoder::deficit(self : Decoder) -> Int

    Decoder::dependent

    fn Decoder::dependent(self : Decoder) -> Int

    Decoder::feedback

    fn Decoder::feedback(self : Decoder) -> Feedback

    Decoder::fork

    fn Decoder::fork(self : Decoder) -> Decoder

    Decoder::generation

    fn Decoder::generation(self : Decoder) -> Generation

    Decoder::is_reduced

    fn Decoder::is_reduced(self : Decoder) -> Bool

    Decoder::known_symbols

    fn Decoder::known_symbols(self : Decoder) -> Array[(Int, Symbols)]

    Decoder::new

    fn Decoder::new(generation : Generation, max_packets? : Int) -> Decoder raise CodeError

    Decoder::pivots

    fn Decoder::pivots(self : Decoder) -> Array[Int]

    Decoder::rank

    fn Decoder::rank(self : Decoder) -> Int

    Decoder::recover

    fn Decoder::recover(self : Decoder) -> Symbols raise CodeError

    Decoder::recover_symbols

    fn Decoder::recover_symbols(self : Decoder) -> Array[Symbols] raise CodeError

    Decoder::remaining_packets

    fn Decoder::remaining_packets(self : Decoder) -> Int

    Decoder::report

    fn Decoder::report(self : Decoder) -> DecodeReport

    Encoder

    pub struct Encoder {
    generation_value : Generation
    source : Array[Symbols]
    }

    Encoder::coded

    fn Encoder::coded(self : Encoder, stream : CoefficientStream, sequence : Int) -> Packet raise CodeError

    Encoder::encode

    fn Encoder::encode(self : Encoder, coefficients : Symbols, sequence : Int) -> Packet raise CodeError

    Encoder::from_symbols

    fn Encoder::from_symbols(generation : Generation, source : Array[Symbols]) -> Encoder raise CodeError

    Encoder::generation

    fn Encoder::generation(self : Encoder) -> Generation

    Encoder::new

    fn Encoder::new(id : Int, input : Symbols, width : Int) -> Encoder raise CodeError

    Encoder::repair

    fn Encoder::repair(self : Encoder, feedback : Feedback, first_sequence : Int) -> Array[Packet] raise CodeError

    Encoder::source_symbols

    fn Encoder::source_symbols(self : Encoder) -> Array[Symbols]

    Encoder::systematic

    fn Encoder::systematic(self : Encoder, index : Int, sequence : Int) -> Packet raise CodeError

    Equation

    pub struct Equation {
    coefficients : Symbols
    payload : Symbols
    }

    Equation::coefficients

    fn Equation::coefficients(self : Equation) -> Symbols

    Equation::new

    fn Equation::new(coefficients : Symbols, payload : Symbols) -> Equation raise CodeError

    Equation::payload

    fn Equation::payload(self : Equation) -> Symbols

    Feedback

    pub struct Feedback {
    generation_value : Generation
    pivot_values : Array[Int]
    }

    Feedback::deficit

    fn Feedback::deficit(self : Feedback) -> Int

    Feedback::generation

    fn Feedback::generation(self : Feedback) -> Generation

    Feedback::missing_pivots

    fn Feedback::missing_pivots(self : Feedback) -> Array[Int]

    Feedback::new

    fn Feedback::new(generation : Generation, pivots : Array[Int]) -> Feedback raise CodeError

    Feedback::pivots

    fn Feedback::pivots(self : Feedback) -> Array[Int]

    Feedback::rank

    fn Feedback::rank(self : Feedback) -> Int

    Feedback::to_wire

    fn Feedback::to_wire(self : Feedback) -> Symbols

    FieldMatrix

    pub struct FieldMatrix {
    cells : Array[Symbols]
    columns : Int
    }

    FieldMatrix::cols

    fn FieldMatrix::cols(self : FieldMatrix) -> Int

    FieldMatrix::identity

    fn FieldMatrix::identity(size : Int) -> FieldMatrix raise CodeError

    FieldMatrix::inverse

    fn FieldMatrix::inverse(self : FieldMatrix) -> FieldMatrix raise CodeError

    FieldMatrix::multiply

    fn FieldMatrix::multiply(self : FieldMatrix, other : FieldMatrix) -> FieldMatrix raise CodeError

    FieldMatrix::new

    fn FieldMatrix::new(rows : Array[Array[Int]]) -> FieldMatrix raise CodeError

    FieldMatrix::rank

    fn FieldMatrix::rank(self : FieldMatrix) -> Int

    FieldMatrix::rows

    fn FieldMatrix::rows(self : FieldMatrix) -> Int

    FieldMatrix::to_arrays

    fn FieldMatrix::to_arrays(self : FieldMatrix) -> Array[Array[Int]]

    FieldMatrix::transpose

    fn FieldMatrix::transpose(self : FieldMatrix) -> FieldMatrix

    FrameReader

    pub struct FrameReader {
    pending : Array[Int]
    byte_count : Int
    frame_count : Int
    byte_limit : Int
    frame_limit : Int
    }

    FrameReader::buffered

    fn FrameReader::buffered(self : FrameReader) -> Int

    FrameReader::feed

    fn FrameReader::feed(self : FrameReader, chunk : Symbols) -> Array[Packet] raise CodeError

    FrameReader::finish

    fn FrameReader::finish(self : FrameReader) -> Unit raise CodeError

    FrameReader::frames

    fn FrameReader::frames(self : FrameReader) -> Int

    FrameReader::new

    fn FrameReader::new(max_bytes? : Int, max_frames? : Int) -> FrameReader raise CodeError

    FrameReader::received_bytes

    fn FrameReader::received_bytes(self : FrameReader) -> Int

    Generation

    pub struct Generation {
    id_value : Int
    count_value : Int
    width_value : Int
    length_value : Int
    }

    Generation::count

    fn Generation::count(self : Generation) -> Int

    Generation::id

    fn Generation::id(self : Generation) -> Int

    Generation::length

    fn Generation::length(self : Generation) -> Int

    Generation::new

    fn Generation::new(id : Int, count : Int, width : Int, length : Int) -> Generation raise CodeError

    Generation::padded_length

    fn Generation::padded_length(self : Generation) -> Int

    Generation::same

    fn Generation::same(self : Generation, other : Generation) -> Bool

    Generation::width

    fn Generation::width(self : Generation) -> Int

    Packet

    pub struct Packet {
    generation_value : Generation
    sequence_value : Int
    equation_value : Equation
    }

    Packet::coefficients

    fn Packet::coefficients(self : Packet) -> Symbols

    Packet::equation

    fn Packet::equation(self : Packet) -> Equation

    Packet::generation

    fn Packet::generation(self : Packet) -> Generation

    Packet::new

    fn Packet::new(generation : Generation, sequence : Int, equation : Equation) -> Packet raise CodeError

    Packet::payload

    fn Packet::payload(self : Packet) -> Symbols

    Packet::sequence

    fn Packet::sequence(self : Packet) -> Int

    Packet::systematic_index

    fn Packet::systematic_index(self : Packet) -> Int?

    Packet::to_wire

    fn Packet::to_wire(self : Packet) -> Symbols

    Packet::wire_length

    fn Packet::wire_length(self : Packet) -> Int

    Packet::with_sequence

    fn Packet::with_sequence(self : Packet, sequence : Int) -> Packet raise CodeError

    Relay

    pub struct Relay {
    decoder : Decoder
    }

    Relay::admit

    fn Relay::admit(self : Relay, packet : Packet) -> Admission raise CodeError

    Relay::basis_packets

    fn Relay::basis_packets(self : Relay, first_sequence : Int) -> Array[Packet] raise CodeError

    Relay::coded

    fn Relay::coded(self : Relay, stream : CoefficientStream, sequence : Int) -> Packet raise CodeError

    Relay::generation

    fn Relay::generation(self : Relay) -> Generation

    Relay::mix

    fn Relay::mix(self : Relay, weights : Symbols, sequence : Int) -> Packet raise CodeError

    Relay::new

    fn Relay::new(generation : Generation, max_packets? : Int) -> Relay raise CodeError

    Relay::rank

    fn Relay::rank(self : Relay) -> Int

    Relay::report

    fn Relay::report(self : Relay) -> DecodeReport

    Replay

    pub struct Replay {
    decoder : Decoder
    event_limit : Int
    event_values : Array[ReplayEvent]
    rejection_count : Int
    }

    Replay::events

    fn Replay::events(self : Replay) -> Array[ReplayEvent]

    Replay::feed_hex

    fn Replay::feed_hex(self : Replay, text : String) -> ReplayEvent raise CodeError

    Replay::feed_wire

    fn Replay::feed_wire(self : Replay, frame : Symbols) -> ReplayEvent raise CodeError

    Replay::new

    fn Replay::new(generation : Generation, max_events? : Int) -> Replay raise CodeError

    Replay::recover

    fn Replay::recover(self : Replay) -> Symbols raise CodeError

    Replay::rejected

    fn Replay::rejected(self : Replay) -> Int

    Replay::report

    fn Replay::report(self : Replay) -> DecodeReport

    ReplayEvent

    pub struct ReplayEvent {
    index_value : Int
    sequence_value : Int?
    rank_value : Int
    status_value : String
    error_value : String?
    }

    ReplayEvent::error_kind

    fn ReplayEvent::error_kind(self : ReplayEvent) -> String?

    ReplayEvent::index

    fn ReplayEvent::index(self : ReplayEvent) -> Int

    ReplayEvent::rank

    fn ReplayEvent::rank(self : ReplayEvent) -> Int

    ReplayEvent::sequence

    fn ReplayEvent::sequence(self : ReplayEvent) -> Int?

    ReplayEvent::status

    fn ReplayEvent::status(self : ReplayEvent) -> String

    ReplayEvent::to_json

    fn ReplayEvent::to_json(self : ReplayEvent) -> String

    SessionPool

    pub struct SessionPool {
    sessions : Array[Decoder]
    generation_limit : Int
    cell_limit : Int
    packet_limit : Int
    cells_used : Int
    }

    SessionPool::admit

    fn SessionPool::admit(self : SessionPool, packet : Packet) -> Admission raise CodeError

    SessionPool::count

    fn SessionPool::count(self : SessionPool) -> Int

    SessionPool::discard

    fn SessionPool::discard(self : SessionPool, id : Int) -> Bool

    SessionPool::ids

    fn SessionPool::ids(self : SessionPool) -> Array[Int]

    SessionPool::new

    fn SessionPool::new(max_generations? : Int, max_cells? : Int, max_packets_per_generation? : Int) -> SessionPool raise CodeError

    SessionPool::recover

    fn SessionPool::recover(self : SessionPool, id : Int) -> Symbols raise CodeError

    SessionPool::reports

    fn SessionPool::reports(self : SessionPool) -> Array[DecodeReport]

    SessionPool::reserved_cells

    fn SessionPool::reserved_cells(self : SessionPool) -> Int

    SessionPool::take

    fn SessionPool::take(self : SessionPool, id : Int) -> Symbols raise CodeError

    Symbols

    pub struct Symbols {
    values : Array[Int]
    }

    Symbols::at

    fn Symbols::at(self : Symbols, index : Int) -> Int raise CodeError

    Symbols::axpy

    fn Symbols::axpy(self : Symbols, factor : Int, other : Symbols) -> Symbols raise CodeError

    Symbols::concat

    fn Symbols::concat(self : Symbols, other : Symbols) -> Symbols raise CodeError

    Symbols::dot

    fn Symbols::dot(self : Symbols, other : Symbols) -> Int raise CodeError

    Symbols::equal

    fn Symbols::equal(self : Symbols, other : Symbols) -> Bool

    Symbols::from_bytes

    fn Symbols::from_bytes(bytes : Bytes) -> Symbols raise CodeError

    Symbols::is_zero

    fn Symbols::is_zero(self : Symbols) -> Bool

    Symbols::length

    fn Symbols::length(self : Symbols) -> Int

    Symbols::new

    fn Symbols::new(values : Array[Int]) -> Symbols raise CodeError

    Symbols::scale

    fn Symbols::scale(self : Symbols, factor : Int) -> Symbols raise CodeError

    Symbols::slice

    fn Symbols::slice(self : Symbols, start : Int, end : Int) -> Symbols raise CodeError

    Symbols::to_array

    fn Symbols::to_array(self : Symbols) -> Array[Int]

    Symbols::to_bytes

    fn Symbols::to_bytes(self : Symbols) -> Bytes

    Symbols::to_hex

    fn Symbols::to_hex(self : Symbols) -> String

    Symbols::zeros

    fn Symbols::zeros(length : Int) -> Symbols raise CodeError

    crc32

    fn crc32(bytes : Symbols) -> UInt

    feedback_from_hex

    fn feedback_from_hex(text : String) -> Feedback raise CodeError

    feedback_from_wire

    fn feedback_from_wire(frame : Symbols) -> Feedback raise CodeError

    field_polynomial

    fn field_polynomial() -> Int

    gf_add

    fn gf_add(left : Int, right : Int) -> Int raise CodeError

    gf_div

    fn gf_div(left : Int, right : Int) -> Int raise CodeError

    gf_inverse

    fn gf_inverse(value : Int) -> Int raise CodeError

    gf_mul

    fn gf_mul(left : Int, right : Int) -> Int raise CodeError

    gf_pow

    fn gf_pow(value : Int, exponent : Int) -> Int raise CodeError

    packet_from_hex

    fn packet_from_hex(text : String) -> Packet raise CodeError

    packet_from_wire

    fn packet_from_wire(frame : Symbols) -> Packet raise CodeError

    symbols_from_hex

    fn symbols_from_hex(text : String, max_bytes? : Int) -> Symbols raise CodeError