par2

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: BSD-3-Clause Imports: 7 Imported by: 0

README

par2

CI Go Reference

Pure-Go (CGO-free) parser, verifier and repairer for PAR2 recovery sets — the format behind the "AutoPAR" feature used to protect Usenet binaries.

  • Parse concatenated .par2 blobs into a RecoverySet, validating every packet's MD5 and skipping unknown or corrupt packets.
  • Verify supplied files against the recovery set using the per-slice MD5+CRC32 checksums (hash based, independent of Reed-Solomon).
  • Repair missing/damaged input slices from the available recovery slices via Reed-Solomon over GF(2^16).
  • Create recovery slices for a set of input files (minimal generator side, enough for AutoPAR self-consistency and round-trip testing).

The Galois-field arithmetic core is reused from github.com/go-erasure/reedsolomon (GF16, primitive polynomial 0x1100B, generator 2), the same field PAR2 uses. CGO_ENABLED=0, Go 1.26.4, stdlib only otherwise.

Install

go get github.com/go-newsgroups/par2

Verify and repair

package main

import (
	"fmt"
	"os"

	"github.com/go-newsgroups/par2"
)

func main() {
	// Load the .par2 recovery data (one or more concatenated blobs).
	blob, _ := os.ReadFile("archive.par2")
	rs, err := par2.Parse(blob)
	if err != nil {
		panic(err)
	}

	// Collect the target files you have on disk.
	files := map[string][]byte{}
	for _, f := range rs.Files {
		if data, err := os.ReadFile(f.Name); err == nil {
			files[f.Name] = data
		}
	}

	// Hash-based verification.
	res, _ := rs.Verify(files)
	if res.Complete {
		fmt.Println("all files present and correct")
		return
	}
	fmt.Printf("damaged/missing; repairable=%v\n", res.Repairable)

	// Reed-Solomon repair.
	if res.Repairable {
		repaired, err := rs.Repair(files)
		if err != nil {
			panic(err)
		}
		for name, data := range repaired {
			_ = os.WriteFile(name, data, 0o644)
		}
		fmt.Println("repaired")
	}
}

Compatibility caveat

Verify is hash based and is correct against real PAR2 files produced by any tool.

Repair and Create implement the Vandermonde Reed-Solomon scheme described in the PAR2 specification on top of the go-erasure/reedsolomon GF(2^16) field, and are validated here by self-consistent round-trip (Create → damage → Repair → bytes match the originals). Byte-exact interoperability with recovery data produced by par2cmdline or QuickPar is NOT yet validated against those tools and is a planned follow-up (real-oracle validation).

License

BSD-3-Clause. See LICENSE.

Documentation

Overview

Package par2 implements a pure-Go (CGO-free) parser, verifier and repairer for PAR2 recovery sets — the format behind the "AutoPAR" feature used to protect Usenet binaries.

The package can:

  • Parse concatenated .par2 blobs into a RecoverySet, validating every packet's MD5 and skipping unknown or corrupt packets.
  • Verify supplied file contents against the recovery set using the per-slice MD5+CRC32 checksums from the Input File Slice Checksum packets (hash based, independent of Reed-Solomon).
  • Repair missing or damaged input slices from the available recovery slices via Reed-Solomon over GF(2^16).
  • Create recovery slices for a set of input files (a minimal generator side, enough for AutoPAR self-consistency and round-trip testing).

Compatibility caveat

Verify is hash based and is correct against real PAR2 files. Repair and Create implement the Vandermonde Reed-Solomon scheme described in the PAR2 specification on top of the go-erasure/reedsolomon GF(2^16) field, and are validated here by self-consistent round-trip (Create → damage → Repair → bytes match). Byte-exact interoperability with recovery data produced by par2cmdline or QuickPar is NOT yet validated against those tools and is a planned follow-up (real-oracle validation).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoMainPacket is returned by Parse when no valid Main packet is found.
	ErrNoMainPacket = errors.New("par2: no main packet found")
	// ErrMissingFileDesc is returned by Parse when the Main packet references a
	// recovery-set file that has no File Description packet.
	ErrMissingFileDesc = errors.New("par2: missing file description packet")
	// ErrNoSliceSize is returned when the slice size is zero.
	ErrNoSliceSize = errors.New("par2: slice size is zero")
	// ErrNotRepairable is returned by Repair when there are more damaged input
	// slices than available recovery slices, or the recovery matrix is singular.
	ErrNotRepairable = errors.New("par2: not enough recovery slices to repair")
	// ErrOddSliceSize is returned by Create for a zero slice size.
	ErrOddSliceSize = errors.New("par2: slice size must be non-zero")
)

Errors returned by the package.

Functions

This section is empty.

Types

type FileSpec

type FileSpec struct {
	ID      [16]byte
	Name    string
	Length  uint64
	FullMD5 [16]byte
	Slices  []SliceChecksum // from the IFSC packet (may be empty if absent)
}

FileSpec describes one recovery-set input file.

type FileStatus

type FileStatus struct {
	Name          string
	Present       bool  // file supplied at all
	Damaged       bool  // some slices fail checksum
	MissingSlices []int // slice indices that are missing/damaged (global slice numbering)
}

FileStatus is the per-file result of a Verify.

type RecoverySet

type RecoverySet struct {
	SliceSize uint64
	Files     []FileSpec      // recovery-set files, in Main-packet order
	Recovery  []RecoverySlice // available recovery slices
	Creator   string
}

RecoverySet is a parsed PAR2 recovery set.

func Create

func Create(sliceSize uint64, files map[string][]byte, recoveryCount int) (*RecoverySet, error)

Create builds recovery slices (exponents 0..recoveryCount-1) for the given input files, returning a RecoverySet suitable for serialization or for round-trip testing.

func Parse

func Parse(blobs ...[]byte) (*RecoverySet, error)

Parse reads all PAR2 packets from one or more concatenated .par2 blobs and assembles a RecoverySet. Packets with a bad header MD5, an unknown type, or a truncated/malformed body are skipped; a valid Main packet is required.

func (*RecoverySet) Repair

func (rs *RecoverySet) Repair(files map[string][]byte) (map[string][]byte, error)

Repair reconstructs missing/damaged input slices from the available recovery slices via Reed-Solomon over GF(2^16), returning the repaired file contents keyed by file name. It errors if the set is not repairable.

func (*RecoverySet) Verify

func (rs *RecoverySet) Verify(files map[string][]byte) (*VerifyResult, error)

Verify checks the supplied file contents against the recovery set using the IFSC MD5+CRC32 per slice and the file length. It is hash based and independent of Reed-Solomon.

type RecoverySlice

type RecoverySlice struct {
	Exponent uint32
	Data     []byte
}

RecoverySlice is one recovery slice (an exponent plus its data).

type SliceChecksum

type SliceChecksum struct {
	MD5   [16]byte
	CRC32 uint32
}

SliceChecksum is the MD5 and CRC32 of a single input slice.

type VerifyResult

type VerifyResult struct {
	Complete   bool // every file fully present & correct
	Files      []FileStatus
	Repairable bool // missing/damaged slices <= available recovery slices
}

VerifyResult reports the state of the target files against the recovery set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL