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
-
Single-part articles — the entire file is encoded in one article. The body contains
=ybegin, the encoded data, and=yendwith a CRC32. Usedecodeandencode. -
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=yendwith a per-part CRC32 (pcrc32=) and optionally the whole-file CRC32 (crc32=). Usedecodeon each article individually, then reassemble using theyencoding_multicrate.
§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 touuencoding-multifor 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§
- Decoded
Part - A successfully decoded yEnc part.
- Encode
Part Options - Parameters for encoding one part of a multi-part yEnc series.
- Yenc
Metadata - Metadata extracted from a yEnc
=ybeginheader line.
Enums§
- Yenc
Error - 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
dataas a single-part yEnc article. - encode_
part - Encode one part of a multi-part yEnc series.