Our home brewed Hamming code uses this format to encode 3 bytes of data:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

a7 | a6 | a5 | a4 | a3 | a2 | a1 | a0 | b7 | b6 | b5 | b4 | b3 | b2 | b1 | p4 | b0 | c7 | c6 | c5 | c4 | c3 | c2 | p3 | c1 | c0 | m1 | p2 | m0 | p1 | p0 | 0 |

Here, bit 0 is not used and always holds a 0. We also have:

1st byte of data= a7 a6 a5 a4 a3 a2 a1 a0

2nd byte of data= b7 b6 b5 b4 b3 b2 b1 b0

3rd byte of data= c7 c6 c5 c4 c3 c2 c1 c0

The modulus bits m1 and m0 are only used in the last 4-byte word of the encoded file. They depend on the original file size (in number of bytes).

m1 m0 = 00 if the file size mod 3 is 0

m1 m0 = 01 if the file size mod 3 is 1

m1 m0 = 10 if the file size mod 3 is 2

The parity bits p4, p3, p2, p1 and p0 are used to ensure that a set of sixteen bit positions have an even number of 1's. (Parity is used here because if one bit in the set is corrupted, then the parity would be wrong.)

Note that each parity bit checks the parity of a set of 16 bits of the codeword and that these sets overlap. Also, each parity bit is in its own set, but not in the set of any other parity bit. For example, the parity bit p4 is in position 16 and none of p0, p1, p2 or p3 involve bit 16. (This is by design and means that we can compute each parity bit without worrying about how another parity bit is set.)

Here is a graphical representation of the bits involved in the computation of each parity bit:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |

p4: | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | ||||||||||||||||

p3: | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | ||||||||||||||||

p2: | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | ||||||||||||||||

p1: | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | ||||||||||||||||

p0: | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |

For example, suppose we want to encode three bytes with hex values 61, 55 and 0A. Recall that it is very easy to convert hex values to binary, so we have:

61 =(These three bytes happen to correspond to the characters0110 0001

55 =0101 0101

0A =0000 1010

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | p4 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | p3 | 1 | 0 | m1 | p2 | m0 | p1 | p0 | 0 |

We assume that these 3 bytes are not the last 3 bytes of the input and
set m1 m0 to 00.
However, even if these 3 bytes *are* the last 3 bytes of the input,
m1 m0 would still be 00. So we can safely assign 0 to m1 and 0 to m0:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | p4 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | p3 | 1 | 0 | 0 | p2 | 0 | p1 | p0 | 0 |

Now recall that p4 is used to make sure that the following bits contain an even number of 1's and that p4 itself is bit 16.

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | p4 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | p3 | 1 | 0 | 0 | p2 | 0 | p1 | p0 | 0 |

Since there are already six 1's among these bits, we have to assign 0 to p4 in order to maintain that there are an even number of 1's. We then have:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | p3 | 1 | 0 | 0 | p2 | 0 | p1 | p0 | 0 |

Next we have to set the parity p3. The set of bit positions associated with p3 is:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | p3 | 1 | 0 | 0 | p2 | 0 | p1 | p0 | 0 |

This time p3 must be set to 1 since there are five 1's in the bit positions marked in red above. So, we have:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | p2 | 0 | p1 | p0 | 0 |

Next we compute p2 using the following bit positions in red. We have to assign 0 to p2 since there are already six 1's in the set.

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | p1 | p0 | 0 |

For p1, we use these positions in red and assign 0 to p1:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | p0 | 0 |

Finally, for p0 we use these positions and set p0 to 1:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |

Thus our final code word in hexadecimal is 6 1 5 4 8 5 8 2:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |

So how would error correction work? Suppose that there was a mistake and bit 22 was corrupted and flipped from 1 to 0:

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |

Recall that bit 22 was involved in the computation of the parity bits p4, p2 and p1. That means when we check these parity bits we will notice that the number of 1's is no longer even.

For example, when we decode the corrupted codeword and check the parity bit p2, we count the number of 1's in the red bits below and notice that there is an odd number of 1's. This tells us that at least one of the red bits has been corrupted.

31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |

Similarly, when we check the parities for the other parity bits, we will notice that the p4 and p1 are also affected but p3 and p0 are not. Furthermore, bit 22 is the only bit position that is involved in the computation of parity bits p4, p2 and p1 but not in the computation of any other parity bit.

p4 | p3 | p2 | p1 | p0 |

X | X | X |

(It is not a coincidence that 22 written in binary is 10110.) Thus, when the parity bits p4, p2, p1, and none other, are wrong, we know that bit 22 must be flipped. Similarly, any 1-bit error can be fixed by this error-correcting code.

Last Modified: 19 Feb 2013 08:18:55 EST by Richard Chang to Spring 2013 CMSC 313 Homepage