skip to content

Which corruptions slip past a one's-complement additive checksum on a configuration blob pushed over a serial link?

level: middleimportance: must knowfreq 54%

answer

  1. cheap sum, structural holes
  2. addition forgets order
  3. a zero word adds nothing
  4. arithmetic modulo 65535
  5. one word gains what another loses

basics

~20 s

An additive sum is unchanged by reordering whole words, by inserting or deleting a word that adds nothing, and by two changes that cancel each other. Any change confined to a single word is caught, which is what makes the holes structural rather than random.

solid answer

~40 s

The sender splits the blob into fixed-width words, adds them with an end-around carry, and sends the complement of the total; the receiver re-adds and expects a constant. Because addition is **commutative**, the total does not depend on word order, so two swapped words pass. Because the arithmetic is modulo 65535 for 16-bit words, both an all-zero and an all-ones word add nothing, so inserting or deleting one passes. And because addition has inverses, a change of `+d` in one word and `-d` in another cancels exactly. What it does catch, with certainty, is any change confined to a single word — a flipped bit, a burst inside that word — with the one exception of swapping an all-zero word for an all-ones word.

code

pseudocode · 5 lines
pseudocode
words     = [0x1234, 0x00FF, 0xABCD]
sum       = ones_complement_sum(words)      # some total S

corrupted = [0x1235, 0x00FE, 0xABCD]        # +1 in word 1, -1 in word 2
sum       = ones_complement_sum(corrupted)  # still S, so the check passes

go deeper

for a junior

Know that a checksum adds the data up and sends the total, and that two errors can cancel so a match is not proof of correctness. The word-order and zero-word holes are fair to miss at this stage.

for a middle

This is your tier: name the three structural holes — order, zero contribution, cancelling pairs — and tie each to a property of addition rather than listing them from memory.

for a senior

Connect the holes to real path failures: a reordered pair of words, a zero-filled short write, corruption upstream of where the sum was taken. Say what you would choose instead when those modes are plausible.

for a principal

Treat it as a cost-versus-coverage decision. An additive sum is almost free and incremental; the question a lead answers is whether the failure modes of the path fall inside its blind spots, and what the cheapest shape change is if they do.

## How the check is formed Split the covered bytes into fixed-width words — 16 bits is the usual choice — add them together, and fold any carry out of the top back into the bottom. That is **one's-complement addition** with an **end-around carry**. The sender transmits the complement of the total in a trailing field; the receiver adds everything it received, the trailing field included, and expects a fixed constant. Two properties of that arithmetic explain every strength and every hole below: 1. the sum is taken **modulo 65535** for 16-bit words, so 0x0000 and 0xFFFF are two spellings of the same value, zero; 2. addition is **commutative and associative**, so the total is a function of the multiset of words, not of the sequence. ## What it always catches Any change confined to a single word alters the total by some non-zero amount modulo 65535, so the recomputed value differs and the check fails. A single flipped bit changes a word by a power of two between 1 and 32768, none of which is zero in this arithmetic; a burst that stays inside one word changes it by some other non-zero amount. The one exception is replacing an all-zero word by an all-ones word or the reverse: that adds nothing, because both are zero here. So the blind spots are never single-word events. Every one of them needs either two coordinated changes or a change that contributes nothing. ## The blind spots | Corruption | Why the check still passes | |---|---| | two whole words swapped | addition commutes, so the total ignores order | | an all-zero or all-ones word inserted or removed | such a word contributes nothing modulo 65535 | | `+d` in one word and `-d` in another | the two changes are additive inverses and cancel | | the same bit position set in one word and cleared in another | a special case of the cancelling pair | | the payload replaced by any block with the same total | the check is a function of the sum and nothing else | Each of these is missed with probability one, not with probability 2 to the power minus sixteen. That distinction is the whole point of the question: a blind spot is not a rare collision, it is a class of corruption the check is structurally unable to see. ## Why widening the field does not help The check maps a block onto a small commutative group, and whatever the group forgets, the check forgets. Order is forgotten because the operation commutes. The identity element is invisible because adding it changes nothing. Inverse pairs vanish because that is what inverses do. A 32-bit additive sum has exactly the same three holes as a 16-bit one — it only shrinks the chance that an unstructured corruption lands on the same total by accident. Closing the order hole requires changing the **shape** of the computation so that a word's position enters it, not widening the result. ## What these look like on a real link - A framing fault delivers two words of a device configuration blob in the wrong order; every field is individually valid, the trailing check agrees, and the device applies a configuration nobody wrote. - A short write leaves a zero-filled tail, or a zero-valued padding word is dropped by an intermediary. The sum is untouched, and the blob is accepted a word shorter or longer than intended. - A corruption upstream of the computation — in the sender's own buffer, before the sum is taken — is summed in as though it were intended. The check then certifies corrupt bytes, because it only ever covers the span between where it was computed and where it is verified. - An intermediary edits the blob and recomputes the trailing field. The check now certifies the last writer, not the original author; a matching value says nothing about who wrote the bytes. ## Why anyone still uses one Cost. One addition per word, no tables, no division, and the sum can be updated incrementally when a small part of the block changes. Where the expected fault really is unstructured noise on a link, an additive sum catches the overwhelming majority of it for almost nothing. The engineering answer is not to reject additive checks but to name their three holes when choosing one, and to pick a different shape when word reordering, truncation or zero padding are plausible failure modes of the path. ## In the interview A strong answer names the blind spots and attributes each to a property of the arithmetic rather than reciting them as trivia. The weak answer treats the check as a general-purpose guarantee — 'the checksum matched, so the blob is fine' — which is wrong in three separate ways and is exactly what the question is probing.

  • Which corruptions does a one's-complement additive checksum always catch?
    Any change confined to a single word. That includes a flipped bit and a burst that stays inside the word, because each shifts the total by a non-zero amount modulo 65535. The single exception is swapping an all-zero word for an all-ones word, since both are zero in that arithmetic. Every blind spot needs two coordinated changes or a contribution of nothing.
  • Why does widening the check from 16 to 32 bits leave the blind spots open?
    Because they come from the operation, not the width. Addition still commutes, the identity still contributes nothing, and inverses still cancel, so reordering, zero-word insertion and cancelling pairs are missed at any width. Widening only shrinks the chance that unstructured corruption happens to land on the same total.
  • Why is 'the trailing field matched, so the blob is what the sender meant' unsafe?
    It covers only the span from where it was computed to where it was verified, and only the corruption patterns the sum is sensitive to. Corruption before the computation is summed in as intended, anyone who rewrites the blob can recompute the field, and the three structural holes pass with probability one.

It is like checking a shopping receipt only by its total: swap two items around, add a free item, or find one line overcharged by exactly what another was undercharged, and the total still agrees.

saying these in an interview costs you the question

  • Says an additive checksum detects any two-bit error
  • Thinks word order is folded into the sum
  • Believes inserting an all-zero word changes the total
  • Assumes the end-around carry makes the sum order-sensitive
  • Claims a matching trailing field proves the blob was not rewritten
  • Thinks a checksum can point at the corrupted word