For transmitting a ciphertext (or any other binary data) over means which only support 5bit ASCII/Baudot characters (for example morse code or RTTY) I am looking for a way to armor my data and have it output in capital letters and numbers only, making sure that a certain amount of characters can be sent or received wrong.

The codegroup utility does one part (ASCII armor to only capital letters) but lacks the FEC, whilst par2 FECs my data but outputs binary.

Does such a combined mechanism exist, posdibly even including the encryption part? I am not specifically looking for programs, any description of how such a thing works would be greatly appreciated and my assumption is that the crypto community would know best.

  • $\begingroup$ So you want encryption and error-correction over 5-bit medium? $\endgroup$
    – DannyNiu
    Commented Mar 27, 2021 at 13:02
  • $\begingroup$ I'm not sure if this question is or should be on-topic here. FWIW, I searched previous meta discussions and… it might be? There's an old meta Q&A from 2011 on the topicality of coding theory questions, which currently has both a "yes" and a "no" answer at 6 (+8/-2) and 5 (+6/-1) score respectively. But there's also a newer question that implicitly assumes they're not, with an answer suggesting asking them on Computer Science instead. So I dunno. Maybe it's still borderline, or maybe consensus has shifted. $\endgroup$ Commented Mar 27, 2021 at 13:45
  • 1
    $\begingroup$ Errors tend to occur in short bursts, and "a certain amount of characters can be sent or received wrong" does not account for that, making it a poor characterization of FEC performance. Somewhat independently: with the notable exceptions of parallel buses, punched tape, and printing+reading/OCR, it is common that 5-bit ASCII is transmitted serially, and that errors loose bit-to-symbol synchronization (in both asynchronous and HDLC bit-to-symbol mapping), sometime causing erasure or insertion of a complete symbol. It is challenging to have good FEC on top of that. $\endgroup$
    – fgrieu
    Commented Mar 27, 2021 at 14:13
  • 2
    $\begingroup$ You need to select the FEC code based on the type of errors you expect; of course, simple 'symbol received incorrectly' is common, as well as burst errors. How about symbol erasure/insertion errors (e.g. you sent ABCDE, they received either ABDE or ABZCDE)? If those errors can occur, the FEC code will need to be selected accordingly... $\endgroup$
    – poncho
    Commented Mar 27, 2021 at 14:22

1 Answer 1


Quick and dirty solution: split the ciphertext to be transmitted into blocks with par2 and encode each block using codegroup. Join the blocks together with some unambiguous and easily identifiable separator.

For this specific combination you could use e.g. ----- as the separator when encoding (and maybe accept any sequence of dashes as the separator when decoding).

When decoding, split the message into blocks, decode each block into bytes using codegroup (discarding any blocks that fail to decode) and them combine them using par2 to (hopefully) recover the original ciphertext.

The reason for this particular combination is the way that par2 and codegroup work:

  • Par2 apparently implements an erasure code that splits the input data into a sequence of blocks (of some arbitrary number of bytes, which I believe is configurable but typically on the order of kilobytes) and adds a number of redundant extra blocks that allow the original data to be recovered even if some blocks are lost. Being an erasure code, it doesn't even attempt to correct errors within blocks — rather, it assumes that all blocks are received either correctly or not at all.

  • Codegroup apparently adds its own CRC checksum to the encoded message to detect errors, and refuses to decode it if the checksum does not match. Thus, even partial message corruption will generally result in full decoding failure.

Thus, there's no point in trying to do error correction within a single codegroup-encoded message — the CRC ensures that, with very high probability, a message either decodes correctly or not at all. (A CRC is not a cryptographic checksum, and it's possible and even quite easy for a deliberate attacker to modify a message in a way that it won't detect. But against random message corruption it's quite effective.)

However, codegroup and par2 actually pair up pretty well, as long as you encode each par2 block separately. Par2 wants corrupted blocks to be discarded, and that's exactly what codegroup does. You just need to make sure that the encoded blocks are combined in a way that lets any intact blocks be reliably separated from each other and from corrupted ones.

The resulting combined scheme may not be optimal in terms of error resistance vs. length expansion, but it should work fairly well at least against rare and/or bursty errors (which, if the message isn't entirely garbled, are likely to leave enough whole blocks intact to allow decoding). If you expect having to deal with a high rate of non-bursty errors (e.g. single bit flips), you may need to tweak the scheme (e.g. by modifying codegroup to apply a convolutional error-correcting code instead of just a CRC to the data).

Anyway, your question doesn't really deal with encryption, so its topicality here seems marginal at best. If you do want to also encrypt your data (which you briefly allude to in your question), the general consensus seems to be that you should do encryption and error correction in separate layers: first encrypt, then apply error correction to the ciphertext.

While error-correcting codes do share some underlying mathematical similarities with some encryption schemes, in practice their goals are different enough that trying to make a single scheme do both at once seems futile. Separating the encryption and the error correction into independent layers simplifies the design and analysis of both components and allows you to use well tested and optimized standard designs for each purpose.

(FWIW, I tried to find a good existing canonical question on that, but the closest I got was Encryption-then-encode or encode-then-encryption?, which isn't really as definitive in its conclusions as I perceive the overall consensus to be. But it'll do for now.)

  • $\begingroup$ I have tried to combine par2 and codegroup, yet any error introduced into codegroup will reak codebroups output completely. $\endgroup$
    – Christian
    Commented Mar 27, 2021 at 16:19
  • $\begingroup$ @Christian: Ah, my mistake. I had misunderstood the nature of both par2 and codegroup. (In particular, I wasn't aware that codegroup had a built-in CRC.) I've rewritten my answer into something hopefully more workable. $\endgroup$ Commented Mar 28, 2021 at 2:26
  • $\begingroup$ Hmm, PAR2 should also have error detection methods, I'm not sure additional measures are required. $\endgroup$
    – Maarten Bodewes
    Commented Mar 28, 2021 at 10:07
  • $\begingroup$ @MaartenBodewes: It may well have, in which case the combination will have two redundant error-detection codes on top of each other. Besides wasting a fairly small (assuming the block size isn't tiny) amount of space and computation time, this should be harmless. $\endgroup$ Commented Mar 28, 2021 at 13:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.