Implementation of Hamming Code in C++

The Hamming Code is an error-detection and error-correction technique developed by Richard Hamming. It introduces redundancy bits (also called parity bits) into a data frame at specific positions that are powers of 2 (positions 1, 2, 4, 8, …). Each redundancy bit covers a set of data bits determined by the binary representation of their positions. At the receiver’s end, the syndrome bits are recalculated and XOR-compared with the received parity bits — a non-zero result identifies the exact bit position where an error occurred.

This C++ program takes a data frame and the number of redundancy bits as input, inserts parity bits at the appropriate positions, simulates a single-bit error at a user-specified location, recalculates the syndrome, and reports the error position.

C++ Program: Hamming Code

#include <iostream.h>
#include <conio.h>
#include <dos.h>

void main()
{
    int dataSize;           // Number of data bits entered by the user
    int redundancyCount;    // Number of redundancy (parity) bits
    int dataBits[30];       // Original data bit array

    cout << "\n Enter frame size: ";
    cin >> dataSize;

    int frameIndex, dataIndex, bitIndex;  // Loop counters

    cout << "\n Enter Frame (bit by bit): ";
    for (frameIndex = 0; frameIndex < dataSize; frameIndex++)
    {
        cin >> dataBits[frameIndex];
    }

    cout << "\n Enter redundancy bits count: ";
    cin >> redundancyCount;

    // Display the entered data frame
    cout << "\n Frame :n ";
    for (frameIndex = 0; frameIndex < dataSize; frameIndex++)
    {
        cout << dataBits[frameIndex] << " ";
    }

    // Reverse dataBits[] so that bit 0 becomes LSB (position 1 in Hamming)
    int tempBits[30];
    for (frameIndex = dataSize - 1, dataIndex = 0; frameIndex >= 0; frameIndex--, dataIndex++)
    {
        tempBits[dataIndex] = dataBits[frameIndex];
    }
    for (frameIndex = 0; frameIndex < dataSize; frameIndex++)
    {
        dataBits[frameIndex] = tempBits[frameIndex];
    }

    // --- Build the Hamming frame with redundancy bit placeholders ---
    int redundancyBitCount = 0;   // Counter for number of redundancy bits placed so far
    int redundancyBits[8];        // Stores computed redundancy bit values

    int hammingFrameLength = 0;   // Total length of Hamming frame (data + parity)
    int hammingFrame[30];         // The Hamming frame array (1-indexed; position 0 unused)

    // Insert -1 as placeholder at power-of-2 positions; insert data bits elsewhere
    int powerOfTwo = 1;
    for (frameIndex = 1, dataIndex = 0; dataIndex < dataSize; frameIndex++)
    {
        if (frameIndex == powerOfTwo)          // Power-of-2 position: reserve for parity
        {
            hammingFrame[frameIndex] = -1;
            powerOfTwo = powerOfTwo * 2;
            redundancyBitCount++;
        }
        else                                   // Data position: insert next data bit
        {
            hammingFrame[frameIndex] = dataBits[dataIndex];
            dataIndex++;
        }
        hammingFrameLength++;
    }

    // Display frame after inserting redundancy placeholders
    cout << "\n";
    cout << "\n Frame after introducing redundancy bits:n ";
    for (frameIndex = hammingFrameLength; frameIndex > 0; frameIndex--)
    {
        cout << hammingFrame[frameIndex] << " ";
    }

    // --- Calculate each redundancy bit using even parity ---
    int redundancyPosition = 0;  // Which redundancy bit is being computed (0-indexed)
    int binaryPos[4];            // Binary representation of a frame position
    int binaryIdx;               // Index for binary array

    redundancyPosition = 0;

    // Scan every position in the Hamming frame
    for (frameIndex = 1; frameIndex <= hammingFrameLength; frameIndex++)
    {
        // Process only the parity bit placeholders
        if (hammingFrame[frameIndex] == -1)
        {
            // Find which bit position (0-indexed) is set in the binary representation
            // of this redundancy bit's position (e.g., position 1 = bit 0, position 2 = bit 1)
            int parityBitPosition = -1;  // Holds the power-of-2 bit index for this parity bit
            int positionValue = frameIndex;
            while (positionValue > 0)
            {
                parityBitPosition++;
                if (positionValue == 1)
                    break;
                else
                    positionValue = positionValue / 2;
            }

            int parityCount = 0;  // Count of 1-bits covered by this parity bit (even parity)

            // Iterate over all frame positions and count covered 1-bits
            for (dataIndex = 1; dataIndex <= hammingFrameLength; dataIndex++)
            {
                // Reset binary representation array
                for (binaryIdx = 0; binaryIdx < 4; binaryIdx++)
                    binaryPos[binaryIdx] = -1;

                // Convert dataIndex to binary
                int tempValue = dataIndex;
                binaryIdx = 0;
                while (tempValue > 0)
                {
                    if (tempValue == 1)
                    {
                        binaryPos[binaryIdx] = 1;
                        break;
                    }
                    else if (tempValue == 0)
                    {
                        binaryPos[binaryIdx] = 0;
                    }
                    else
                    {
                        binaryPos[binaryIdx] = tempValue % 2;
                        tempValue = tempValue / 2;
                    }
                    binaryIdx++;
                }

                // If this position has a 1 at parityBitPosition in its binary form,
                // it is covered by the current parity bit
                if (binaryPos[parityBitPosition] == 1)
                {
                    if (hammingFrame[dataIndex] == 1)
                        parityCount++;
                }
            }

            // Assign parity bit: 0 for even count, 1 for odd count
            if (parityCount % 2 == 0)
            {
                hammingFrame[frameIndex] = 0;
                redundancyBits[redundancyPosition] = 0;
            }
            else
            {
                hammingFrame[frameIndex] = 1;
                redundancyBits[redundancyPosition] = 1;
            }
            redundancyPosition++;

            // Print the current state of the frame after setting this parity bit
            cout << "\n R" << redundancyPosition << " = " << redundancyBits[redundancyPosition - 1] << "\t New Frame";
            for (dataIndex = hammingFrameLength; dataIndex > 0; dataIndex--)
            {
                cout << " " << hammingFrame[dataIndex];
            }
        }
    }

    // --- Simulate a single-bit error ---
    int errorBitPosition;
    cout << "\n";
    cout << "\n Enter bit position where error occurred: ";
    cin >> errorBitPosition;

    cout << "\n Bit at position " << errorBitPosition << " is " << hammingFrame[errorBitPosition];

    // Flip the bit at the error position
    if (hammingFrame[errorBitPosition] == 1)
        hammingFrame[errorBitPosition] = 0;
    else
        hammingFrame[errorBitPosition] = 1;

    cout << " and now changed to " << hammingFrame[errorBitPosition];

    // Print the corrupted frame
    cout << "\n New Frame is";
    for (frameIndex = hammingFrameLength; frameIndex > 0; frameIndex--)
    {
        cout << " " << hammingFrame[frameIndex];
    }

    // --- Recalculate syndrome bits after the error ---
    redundancyPosition = 0;
    powerOfTwo = 1;

    for (frameIndex = 1; frameIndex <= hammingFrameLength; frameIndex++)
    {
        if (frameIndex == powerOfTwo)  // Process only parity bit positions
        {
            int parityBitPosition = -1;
            int positionValue = frameIndex;
            while (positionValue > 0)
            {
                parityBitPosition++;
                if (positionValue == 1)
                    break;
                else
                    positionValue = positionValue / 2;
            }

            int parityCount = 0;

            for (dataIndex = 1; dataIndex <= hammingFrameLength; dataIndex++)
            {
                for (binaryIdx = 0; binaryIdx < 4; binaryIdx++)
                    binaryPos[binaryIdx] = -1;

                int tempValue = dataIndex;
                binaryIdx = 0;
                while (tempValue > 0)
                {
                    if (tempValue == 1)
                    {
                        binaryPos[binaryIdx] = 1;
                        break;
                    }
                    else if (tempValue == 0)
                    {
                        binaryPos[binaryIdx] = 0;
                    }
                    else
                    {
                        binaryPos[binaryIdx] = tempValue % 2;
                        tempValue = tempValue / 2;
                    }
                    binaryIdx++;
                }

                if (binaryPos[parityBitPosition] == 1)
                {
                    if (hammingFrame[dataIndex] == 1)
                        parityCount++;
                }
            }

            if (parityCount % 2 == 0)
            {
                hammingFrame[frameIndex] = 0;
                redundancyBits[redundancyPosition] = 0;
            }
            else
            {
                hammingFrame[frameIndex] = 1;
                redundancyBits[redundancyPosition] = 1;
            }

            redundancyPosition++;
            powerOfTwo = powerOfTwo * 2;
        }
    }

    // Display recalculated syndrome bits
    cout << "\n Redundancy bits: ";
    for (frameIndex = 0; frameIndex < redundancyBitCount; frameIndex++)
    {
        cout << " " << redundancyBits[frameIndex];
    }

    // Calculate error position from syndrome (weighted sum of redundancy bits)
    int errorPosition = 0;
    for (frameIndex = 0, bitIndex = 1; frameIndex < redundancyBitCount; frameIndex++)
    {
        if (redundancyBits[frameIndex] == 1)
        {
            errorPosition = errorPosition + bitIndex;
        }
        bitIndex = bitIndex * 2;
    }

    cout << "\n Error is at position: " << errorPosition;

    getch();
}

How the Code Works

Step 1 — Input: The user enters the data frame bit by bit and specifies the number of redundancy bits required.

Step 2 — Frame Construction: The program builds the Hamming frame by inserting placeholder values (-1) at positions that are powers of 2 (1, 2, 4, 8, …) and filling the remaining positions with the data bits in order.

Step 3 — Parity Calculation: For each redundancy bit position, the program checks all frame positions whose binary representation has a 1 at the corresponding bit index. It counts how many of those positions hold a 1-bit and sets the parity bit to maintain even parity.

Step 4 — Error Simulation: The user specifies a bit position. The program flips that bit (0→1 or 1→0) to simulate a transmission error.

Step 5 — Syndrome Calculation: The parity bits are recalculated over the corrupted frame. Any parity bit that now fails contributes its positional weight (1, 2, 4, …) to the syndrome sum.

Step 6 — Error Location: The syndrome sum directly gives the position of the erroneous bit in the Hamming frame. A syndrome of 0 means no error was detected.

Sample Output


 Enter frame size: 7

 Enter Frame (bit by bit): 1
0
0
1
1
0
1

 Enter redundancy bits count: 4

 Frame :
 1 0 0 1 1 0 1

 Frame after introducing redundancy bits:
 1 0 0 -1 1 1 0 -1 1 -1 -1
 R1 = 1   New Frame 1 0 0 -1 1 1 0 -1 1 -1 1
 R2 = 0   New Frame 1 0 0 -1 1 1 0 -1 1 0 1
 R3 = 0   New Frame 1 0 0 -1 1 1 0 0 1 0 1
 R4 = 1   New Frame 1 0 0 1 1 1 0 0 1 0 1

 Enter bit position where error occurred: 7

 Bit at position 7 is 1 and now changed to 0
 New Frame is 1 0 0 1 0 1 0 0 1 0 1
 Redundancy bits:  1 1 1 0
 Error is at position: 7

Output Explanation

The original 7-bit data frame 1 0 0 1 1 0 1 is expanded to an 11-bit Hamming frame. The program places -1 at positions 1, 2, 4, and 8 as parity bit placeholders. After computing parity, R1=1, R2=0, R3=0, R4=1 are inserted, giving the complete transmitted frame 1 0 0 1 1 1 0 0 1 0 1.

An error is introduced at bit position 7 (changing 1 to 0). The syndrome recalculation yields redundancy bits 1 1 1 0, which corresponds to the weighted sum 1×1 + 1×2 + 1×4 + 0×8 = 7. This correctly identifies position 7 as the error location.

See Also

Conclusion

Hamming Code is one of the most elegant error-correction mechanisms in digital communications. By embedding redundancy bits at power-of-2 positions, it achieves single-bit error correction with minimal overhead — an 11-bit Hamming frame can carry 7 data bits while detecting and correcting any single-bit error. Understanding this algorithm provides a strong foundation for studying more advanced forward error correction (FEC) codes used in modern network protocols and storage systems.

5 thoughts on “Implementation of Hamming Code in C++”

  1. you forgot using namespace st; , is only #include and the main is int main() don’t void main()

    #include
    #include
    #include
    using namespace std;
    int main()

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.