Introduction
Transferring binary files over Usenet used to mean a 33% size penalty from base64 or uuencoding. yEnc fixed that by encoding most bytes as-is, escaping only the handful of control characters that would break NNTP line handling. This tool encodes and decodes yEnc streams in your browser, showing the byte transformation, critical-byte escaping, and CRC32 checksum verification in real time. Paste text or a yEnc body with =ybegin/=yend headers, and the output updates instantly. Nothing leaves your device.
What this tool does
- Encode text to yEnc format using the (byte - 42) mod 256 transformation, with escaping for NUL (0x00), LF (0x0A), CR (0x0D), equals (0x3D), and dot (0x2E)
- Decode yEnc streams back to the original bytes, automatically stripping =ybegin and =yend framing lines when present
- Compute and display the CRC32 checksum (polynomial 0xEDB88320) for every encoding, and verify it against the =yend trailer on decode
- Show a per-byte encoding table for the first 50 bytes, marking which bytes are critical and how they are escaped
- Generate proper =ybegin headers with size and name fields, plus =yend trailers carrying the CRC32 value
- Run entirely client-side: input text and encoded output never touch a server
How this tool works
The tool implements the yEnc transformation directly in TypeScript. For encoding, each input byte is transformed by subtracting 42 modulo 256: `output = (input - 42) & 0xFF`. If the result is one of five critical bytes (0x00 NUL, 0x0A LF, 0x0D CR, 0x3D equals, or 0x2E dot), the tool inserts an escape byte (0x3D) before it and subtracts 0x40 from the critical byte modulo 256. This keeps the encoded stream safe for NNTP line-oriented transport.
The CRC32 checksum uses the standard reflected polynomial 0xEDB88320, initialized to 0xFFFFFFFF and XORed with 0xFFFFFFFF at the end. The tool computes this over the original input bytes and embeds it in the =yend trailer as an 8-character lowercase hex string. On decode, it strips the =ybegin and =yend lines, reverses the escape sequences, reconstructs the original bytes, recomputes the CRC32, and compares it against the trailer value.
The encoding steps panel shows the first 50 bytes with their input value, whether the transformed byte was critical, and the exact output bytes produced. This makes the escaping mechanism visible, which is the part of yEnc that most other tools hide.
How yEnc encoding works
yEnc was introduced by Juergen Helbing in 2001 as an alternative to uuencoding and base64 for Usenet binary posts. The specification is documented at yenc.org and the format was later described in RFC 2984, which registered the `application/yenc` MIME type.
The core idea is simple. Instead of mapping every 3 bytes to 4 ASCII characters (which adds 33% overhead like base64), yEnc passes most bytes through unchanged after a fixed offset. Only 5 out of 256 possible byte values need escaping because they would interfere with NNTP's line-based protocol. This means the encoded output is nearly the same size as the input, typically within 1-2% for random binary data.
The =ybegin header carries metadata: line length, total size, and filename. The =yend trailer carries the size again plus a CRC32 checksum. Multi-part posts use =ypart headers between =ybegin and =yend. The CRC32 lets news clients verify that each part arrived intact, which was a real concern on Usenet where articles could be dropped or corrupted in transit.
yEnc never became an IETF standard. The RFC only registered the MIME type. The format was widely deployed in newsreaders like GrabIt, NewsBin, and pan throughout the 2000s. For modern binary transport, base64 in MIME messages (RFC 2045) remains the standard, but yEnc is still encountered in archived Usenet posts and CTF challenges.
How to use this tool
- Choose Encode or Decode mode using the toggle buttons
- For encoding: paste or type your text in the input field. The tool converts it to UTF-8 bytes and applies the yEnc transformation
- For decoding: paste a yEnc stream. If it includes =ybegin and =yend lines, the tool extracts the body automatically and verifies the CRC32
- Watch the CRC32 panel: on encode it shows the computed checksum. On decode it shows whether the checksum matches the =yend trailer
- Expand the encoding steps table to see per-byte input values, critical-byte flags, and output bytes for the first 50 bytes
- Click Swap encode/decode to reverse the operation and feed the output back as input
Real-world examples
Encoding a short text string
Input: `Hello` (5 bytes: 0x48 0x65 0x6C 0x6C 0x6F). Each byte has 42 subtracted: 0x1E 0x3F 0x42 0x42 0x45. None of these are critical bytes, so no escaping is needed. The output body is 5 bytes. The =ybegin header reads `=ybegin line=128 size=5 name=file.bin` and the =yend trailer carries the CRC32 of the original 5 bytes.
Critical byte escaping in action
Input byte 0x2C (comma) transforms to (0x2C - 42) = 0x02, which is not critical and passes through. But input byte 0x6C transforms to (0x6C - 42) = 0x42, also safe. Input byte 0x44 transforms to (0x44 - 42) = 0x0A (LF), which IS critical. The encoder outputs 0x3D (escape) followed by (0x0A + 0x100 - 0x40) = 0xCA. The steps table marks this byte as `critical: yes` and shows both output bytes.
Decoding with CRC32 verification
Paste a full yEnc message with `=ybegin line=128 size=11 name=test.bin` and `=yend size=11 crc32=a1b2c3d4`. The tool strips the header and trailer, decodes the body bytes by reversing the offset and unescaping, then recomputes the CRC32 over the decoded output. If the computed CRC matches `a1b2c3d4`, the verification panel shows `checksum matches`. If any byte was corrupted in transit, the checksum will mismatch and the tool reports it.
Decoding without headers
If you paste only the encoded body (no =ybegin or =yend lines), the tool still decodes it by reversing the transformation on every byte. The CRC32 is computed and displayed, but there is no trailer to verify against, so the verification panel stays empty. This is useful for CTF challenges where only the payload is provided.
Comparison with similar methods
| Method | Complexity | Typical use |
|---|---|---|
| yEnc | Offset + escape 5 bytes, ~1-2% overhead | Usenet binary posts, NNTP transport |
| Base64 | 6-bit alphabet, 33% overhead | Email MIME, JWT, web data URIs |
| UUencode | 6-bit alphabet, 33% overhead | Legacy Usenet, email attachments |
| BinHex 4.0 | RLE + 6-bit alphabet, variable overhead | Classic Macintosh file transfer |
| Quoted-Printable | Escape non-printable bytes, up to 200% overhead | Email text with non-ASCII characters |
Limitations or considerations
yEnc is an encoding, not encryption. It provides zero confidentiality. The CRC32 checksum detects accidental corruption but offers no protection against intentional tampering, since CRC32 is not a cryptographic hash.
The tool processes text input, not raw binary files. For large binary files, use a dedicated newsreader or command-line yEnc tool. The encoding steps table is limited to the first 50 bytes for performance reasons.
yEnc assumes an 8-bit clean transport. If the channel strips the high bit (as some legacy SMTP relays did), the encoded data will be corrupted. This is why yEnc was used on Usenet (which is 8-bit clean) rather than in email (which historically was 7-bit). For email attachments, Base64 Encode/Decode remains the correct choice.
This tool does not implement multi-part yEnc (=ypart headers). Each encode produces a single-part message. For comparison with other binary-to-text encodings, see the BinHex Encoder and UUencode tools.
Frequently asked questions
What is 'yEnc' and why was it created?
yEnc is a binary-to-text encoding designed by Juergen Helbing in 2001 for Usenet binary transfers. It was created because base64 and uuencoding add 33% overhead, which wasted bandwidth and storage on Usenet servers. yEnc passes most bytes through with only a fixed offset, escaping just 5 critical byte values, so the encoded output is typically within 1-2% of the original size.
Why does yEnc subtract 42 from each byte?
The offset of 42 is arbitrary but chosen to shift the most common byte values away from the critical range. After subtracting 42, bytes that would land on NUL (0x00), LF (0x0A), CR (0x0D), equals (0x3D), or dot (0x2E) are escaped. The value 42 was selected by the original author and became part of the de facto standard.
What is the CRC32 checksum in the =yend trailer?
The CRC32 is a 32-bit cyclic redundancy check computed over the original (unencoded) data using the polynomial 0xEDB88320. It is included in the =yend trailer as an 8-character hex string. News clients recompute the CRC32 after decoding and compare it to detect transmission errors. It is not a security measure.
Can yEnc handle multi-part posts?
Yes, the yEnc format supports multi-part posts using =ypart headers between =ybegin and =yend. However, this tool only produces single-part messages. For multi-part encoding, use a dedicated newsreader like GrabIt or a command-line yEnc encoder.
Is yEnc still used today?
yEnc is largely obsolete for new use but still appears in archived Usenet posts, CTF challenges, and legacy binary groups. Modern binary transport typically uses base64 in MIME messages or direct binary protocols. The format was never fully standardized as an IETF spec; RFC 2984 only registered the MIME type.
How does yEnc compare to base64?
Base64 maps every 3 bytes to 4 ASCII characters, adding 33% overhead. yEnc passes most bytes through with a fixed offset, escaping only 5 critical values, so overhead is typically 1-2%. However, yEnc requires an 8-bit clean transport, while base64 produces 7-bit-safe ASCII that works over any channel. See the Base64 Encode/Decode tool for comparison.
Conclusion
yEnc solved a real bandwidth problem on Usenet by avoiding the 33% overhead that base64 and uuencoding impose. The offset-and-escape approach is simple but effective when the transport is 8-bit clean. This tool makes the encoding visible: you can see which bytes are critical, how they are escaped, and whether the CRC32 checksum verifies. For modern binary-to-text needs, compare with Base64 Encode/Decode, BinHex Encoder, or UUencode.