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
- Implementation of Cyclic Redundancy Check (CRC) Algorithm in C++ — another error-detection method using polynomial division
- Illustrating Working of Bit-Map Protocol with C++ Program — MAC layer channel access control
- Implementation of Dijkstra Algorithm in C++ — shortest path routing algorithm
- Implementation of Distance Vector Routing (DVR) Algorithm in C++ — routing table computation
- Implementing Socket Programming in Java — TCP client-server communication
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.
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()
not working
Helpful….
why are we reversing the frame?
This one might help you: https://www.codespeedy.com/hamming-code-in-cpp/