Skip to main content

Crate yencoding

Crate yencoding 

Source
Expand description

yEnc encoding and decoding.

§Background

yEnc (short for “Why Encode?”) was developed by Jürgen Helbing and released in 2001 as a replacement for UUencode and Base64 on Usenet. The key insight is that most byte values (252 out of 256) pass through the encoding with only a single-byte overhead (add 42, mod 256), instead of the 33% overhead of Base64 or the similar overhead of UUencode. In practice yEnc articles are only 1–2% larger than the raw binary they carry.

yEnc became the dominant Usenet binary encoding in the early 2000s and remains in use today, especially in NZB-based binary download ecosystems.

§Two use cases

  1. Single-part articles — the entire file is encoded in one article. The body contains =ybegin, the encoded data, and =yend with a CRC32. Use decode and encode.

  2. Multi-part articles — large files are split across numbered articles. Each article carries =ybegin part= total=, a =ypart begin= end= line giving its byte range, the encoded data, and =yend with a per-part CRC32 (pcrc32=) and optionally the whole-file CRC32 (crc32=). Use decode on each article individually, then reassemble using the yencoding_multi crate.

§Relationship to other crates in this workspace

  • uuencoding — handles the older UUencode format. yEnc replaced UUencode on Usenet but both still appear in email archives.
  • yencoding-multi — multi-part reassembly for yEnc, analogous to uuencoding-multi for UUencode. This crate is a dependency of that one.

This crate has no dependency on mime-tree, uuencoding, or any other workspace crate.

§Not in scope

  • NZB files — NZB is an XML format that describes which Usenet articles carry the parts of a file. Parsing NZB is a separate concern; this crate operates on raw article bodies, not NZB metadata.
  • NNTP protocol — fetching articles from an NNTP server is the caller’s responsibility. This crate operates on byte slices.
  • SIMD optimisation — the byte transform is a single subtraction per byte and already vectorises automatically at -O2; explicit SIMD adds complexity without measurable benefit.

§Security note

Unlike Base64, yEnc-encoded data is approximately the same size as the original binary (1–2% overhead). There is no significant size amplification from decoding. However, decoded bytes may represent a compressed archive (.tar.gz, .zip, .rar, etc.). This crate never decompresses the output. Any subsequent decompression is the caller’s responsibility and must be independently guarded against decompression-bomb attacks before beginning decompression.

§Quick start

// Decode a single-part yEnc article.
// Oracle: bytes [0,1,2] encode as ['*','+',','] (add 42, no escapes needed).
// CRC32 of [0,1,2]: python3 -c "import binascii; print(hex(binascii.crc32(bytes([0,1,2]))&0xffffffff))"
// → 0x0854897f
let raw_article: &[u8] = b"\
    =ybegin line=128 size=3 name=hi.bin\r\n\
    *+,\r\n\
    =yend size=3 crc32=0854897f\r\n";
let part = yencoding::decode(raw_article).unwrap();
assert_eq!(part.data, &[0u8, 1, 2]);
assert_eq!(part.metadata.filename, "hi.bin");
assert!(part.crc32_verified);
// Encode bytes as a single-part yEnc article.
let encoded = yencoding::encode(b"\x00\x01\x02", "hi.bin", yencoding::DEFAULT_LINE_LENGTH);
assert!(encoded.starts_with(b"=ybegin"));
assert!(encoded.ends_with(b"\r\n"));

Structs§

DecodedPart
A successfully decoded yEnc part.
EncodePartOptions
Parameters for encoding one part of a multi-part yEnc series.
YencMetadata
Metadata extracted from a yEnc =ybegin header line.

Enums§

YencError
Errors produced by yEnc decode operations.

Constants§

DEFAULT_LINE_LENGTH
Default line length for yEnc encoding, matching the yEnc spec recommendation.

Functions§

decode
Decode a yEnc article from raw bytes.
encode
Encode data as a single-part yEnc article.
encode_part
Encode one part of a multi-part yEnc series.