+/* Correct any single-bit error -- assumes there are no double-bit errors */
+unsigned correct_single_bit_error(unsigned code)
+{
+ unsigned bits[CODE_BITS];
+ unsigned parity[PARITY_BITS];
+ unsigned i, bp = 0;
+
+ parity[4] = 0;
+
+ for (i = 0; i < CODE_BITS; ++i) {
+ bits[i] = (code & (1 << i)) ? 1 : 0;
+ }
+ for (i = 1; i < CODE_BITS; ++i) {
+ parity[4] ^= bits[i];
+ }
+
+ parity[0] = bits[PARITY_BITS+0] ^ bits[PARITY_BITS+1] ^ bits[PARITY_BITS+3] ^ bits[PARITY_BITS+4] ^ bits[PARITY_BITS+6] ^ bits[PARITY_BITS+8] ^ bits[PARITY_BITS+10];
+ parity[1] = bits[PARITY_BITS+0] ^ bits[PARITY_BITS+2] ^ bits[PARITY_BITS+3] ^ bits[PARITY_BITS+5] ^ bits[PARITY_BITS+6] ^ bits[PARITY_BITS+9] ^ bits[PARITY_BITS+10];
+ parity[2] = bits[PARITY_BITS+1] ^ bits[PARITY_BITS+2] ^ bits[PARITY_BITS+3] ^ bits[PARITY_BITS+7] ^ bits[PARITY_BITS+8] ^ bits[PARITY_BITS+9] ^ bits[PARITY_BITS+10];
+ parity[3] = bits[PARITY_BITS+4] ^ bits[PARITY_BITS+5] ^ bits[PARITY_BITS+6] ^ bits[PARITY_BITS+7] ^ bits[PARITY_BITS+8] ^ bits[PARITY_BITS+9] ^ bits[PARITY_BITS+10];
+
+ for (i = 0; i < PARITY_BITS - 1; ++i) {
+ if (parity[i] != bits[PARITY_BITS - 1 - i]) {
+ bp |= (1 << i);
+ }
+ }
+
+ if (bp != 0) {
+ /* flip the wrong bit */
+ code ^= (1 << permutation_table[bp]);
+ parity[4] ^= 1;
+ }
+
+ /* recompute the lower parity */
+ return (code & ~1) | parity[4];
+}
+