Hamming code Implementation in C++ with receiver side verification of code
Last Updated : 15 Mar, 2023
Hamming code is an error-correcting code used for detecting and correcting errors in data transmission. It adds redundant bits to the data being transmitted which can be used to detect and correct errors that may occur during transmission. Developed by Richard W. Hamming in the 1950s, it is widely used in applications where reliable data transmission is critical, such as computer networks and telecommunication systems.
To implement the Hamming code in C++, we can use bitwise operations and arrays to represent the data and the redundant bits. The following code snippet demonstrates how to implement the Hamming code in C++ with receiver-side verification:
Example:
C++ #include <iostream> using namespace std; // function to calculate the parity bit for a given position int parity(int n, int *arr) { int p = 0; for (int i = 0; i < n; i++) { if (i != (1 << p) - 1) { p++; } else { p++; i += (1 << p) - 2; } } int sum = 0; for (int i = 0; i < n; i++) { if ((i & (1 << p - 1)) == 0) { sum ^= arr[i]; } } return sum; } // function to encode the data using the Hamming code void encode(int *data, int n, int *encoded) { int r = 0; while ((1 << r) < n + r + 1) { r++; } int j = 0; for (int i = 0; i < n + r; i++) { if ((i & (i + 1)) == 0) { encoded[i] = 0; } else { encoded[i] = data[j]; j++; } } for (int i = 0; i < r; i++) { int p = parity(n + r, encoded); encoded[(1 << i) - 1] = p; } } // function to decode the data using the Hamming code bool decode(int *data, int n, int *received) { int r = 0; while ((1 << r) < n + r + 1) { r++; } int error = 0; for (int i = 0; i < r; i++) { int p = parity(n + r, received); if (p != received[(1 << i) - 1]) { error += (1 << i) - 1; } } if (error != 0) { received[error - 1] ^= 1; } int j = 0; for (int i = 0; i < n + r; i++) { if ((i & (i + 1)) != 0) { data[j] = received[i]; j++; } } return error == 0; } int main() { int n = 4; // size of data int r = 3; // number of redundant bits int data[n] = {1, 0, 1, 1}; // data to be transmitted int encoded[n + r] = {0}; // encoded data
C++ #include <iostream> #include <string> #include <algorithm> using namespace std; class hamming{ public: string data; //it is the raw data received int m , r = 0; // n is the length of raw data and r is the number of redundant bits char * msg; // it will store the all bits (data + redundant). We made it dynamic because at compile time we dont know how much redundant bits will be there, we will initialize memory to it once we know the number of redundant bits. hamming(string data){ this->data = data; //reversing the data received reverse(data.begin(),data.end()); m = data.size(); int power = 1; //finding the number of redundant bits and storing them in r while(power < (m + r + 1)){ r++; power*=2; } //Allocating memory to our dynamic msg array(Note we are using one based indexing). msg = new char[m+r+1]; int curr = 0; //initializing the msg with data bits and for redundant bits, an initial value of n for(int i = 1 ; i <= m+r ; i++){ if(i & (i-1)){ msg[i] = data[curr++]; } else msg[i] = 'n'; } //function call to set the redundant bits setRedundantBits(); } //function to show the whole msg void showmsg(){ cout << "the data packet to be sent is : "; for(int i = m+r ; i >= 1 ; i--){ cout << msg[i] << " "; } cout << endl; } void setRedundantBits(){ //for first redundant bit, check all those data bits at index where the first bit of index is set(1) similarly for second redundant bit, check all those data bits at index where the second bit of index is set(1), similarly for third redundant bit check all those data bits at index where the third bit of index is set to 1 and so on. int bit = 0; //outer loop runs for redundant bits (1 ,2 ,4 ,8 ....) for(int i = 1 ; i <= m+r ; i*=2){ int count = 0; //inner loop runs for data bits for(int j = i+1 ; j<=m+r ; j++){ // checking if the data bit corresponds to our redundant bit or not using bit manipulation if(j & (1 << bit)){ if(msg[j] == '1') count++; // counting the number of ones in corresponding data bits } } //setting up redundant bits if(count & 1) msg[i] = '1'; else msg[i] = '0'; //increasing the bit position. bit++; } //showing up the message to be sent(data + redundant) showmsg(); } void receiver(){ //this ans will store the redundant bits, if they were right then according to even parity they will store 0 else if some error was made in a bit it will store 1 string ans = ""; int bit = 0; //this loop corresponds to the logic used in set redundant bits function for(int i = 1 ; i <= m+r ; i*=2){ int count = 0; for(int j = i+1 ; j<=m+r ; j++){ if(j & (1 << bit)){ if(msg[j] == '1') count++; } } //incrementing the ans variable with the parity of redundant bit // if it was right then add 0 else 1 if(count & 1){ if(msg[i] == '1') ans.push_back('0'); else ans.push_back('1'); } else{ if(msg[i]=='0') ans.push_back('0'); else ans.push_back('1'); } bit++; } // if the ans had any occurrence of 1 then there is some fault if(ans.find('1') != string::npos){ int power = 1; int wrongbit = 0; //evaluating the binary expression of ans variable for(int i = 0 ; i < ans.size() ; i++){ if(ans[i]=='1') wrongbit+=power; power*=2; } cout << "bit number " << wrongbit << " is wrong and having error " << endl; } // if the ans dont have any occurrence of 1 then it is correct else{ cout << "correct data packet received " << endl; } } }; int main(){ string data = "1011001"; hamming h(data); // manipulating any ith data bit to check if receiver is detecting a error in that bit. If you eliminate the following line then correct code will be sent to receiver following that no error is received //h.msg[i] == '0' ? h.msg[i] = '1' : h.msg[i] = '0'; h.receiver(); return 0; } //time complexity = O(nlogn) where , n = databits + redundant bits //this code is contributed by Mayank Sharma.
Outputthe data packet to be sent is : 1 0 1 0 1 0 0 1 1 1 0 correct data packet received
Pre-requisite: Hamming Code
Given a message bit in the form of an array msgBit[], the task is to find the Hamming Code of the given message bit.
Examples:
Input: S = "0101"
Output:
Generated codeword:
r1 r2 m1 r4 m2 m3 m4
0 1 0 0 1 0 1
Explanation:
Initially r1, r2, r4 is set to '0'.
r1 = Bitwise XOR of all bits position that has '1' in its 0th-bit position.
r2 = Bitwise XOR of all bits that has '1' in its 1st-bit position.
r3 = Bitwise XOR of all bits that has '1' in its 2nd-bit position.
Input: S = "0111"
Output:
Generated codeword:
r1 r2 m1 r4 m2 m3 m4
0 0 0 1 1 1 1
Approach: The idea is to first find the number of redundant bits which can be found by initializing r with 1 and then incrementing it by 1 each time while 2r is smaller than (m + r + 1) where m is the number of bits in the input message. Follow the below steps to solve the problem:
- Initialize r by 1 and increment it by 1 until 2r is smaller than m+r+1.
- Initialize a vector hammingCode of size r + m which will be the length of the output message.
- Initialize all the positions of redundant bits with -1 by traversing from i = 0 to r - 1 and setting hammingCode [2i - 1] = -1. Then place the input message bits in all the positions where hammingCode[j] is not -1 in order where 0 <= j < (r + m).
- Initialize a variable one_count with 0 to store the number of ones and then traverse from i = 0 to (r + m - 1).
- If the current bit i.e., hammingCode[i] is not -1 then find the message bit containing set bit at log2(i+1)th position by traversing from j = i+2 to r+m by incrementing one_count by 1 if (j & (1<<x)) is not 0 and hammingCode[j - 1] is 1.
- If for index i, one_count is even, set hammingCode[i] = 0 otherwise set hammingCode[i] = 1.
- After traversing, print the hammingCode[] vector as the output message.
Below is the implementation of the above approach:
C // C program for the above approach #include <math.h> #include <stdio.h> // Store input bits int input[32]; // Store hamming code int code[32]; int ham_calc(int, int); void solve(int input[], int); // Function to calculate bit for // ith position int ham_calc(int position, int c_l) { int count = 0, i, j; i = position - 1; // Traverse to store Hamming Code while (i < c_l) { for (j = i; j < i + position; j++) { // If current bit is 1 if (code[j] == 1) count++; } // Update i i = i + 2 * position; } if (count % 2 == 0) return 0; else return 1; } // Function to calculate hamming code void solve(int input[], int n) { int i, p_n = 0, c_l, j, k; i = 0; // Find msg bits having set bit // at x'th position of number while (n > (int)pow(2, i) - (i + 1)) { p_n++; i++; } c_l = p_n + n; j = k = 0; // Traverse the msgBits for (i = 0; i < c_l; i++) { // Update the code if (i == ((int)pow(2, k) - 1)) { code[i] = 0; k++; } // Update the code[i] to the // input character at index j else { code[i] = input[j]; j++; } } // Traverse and update the // hamming code for (i = 0; i < p_n; i++) { // Find current position int position = (int)pow(2, i); // Find value at current position int value = ham_calc(position, c_l); // Update the code code[position - 1] = value; } // Print the Hamming Code printf("\nThe generated Code Word is: "); for (i = 0; i < c_l; i++) { printf("%d", code[i]); } } // Driver Code void main() { // Given input message Bit input[0] = 0; input[1] = 1; input[2] = 1; input[3] = 1; int N = 4; // Function Call solve(input, N); }
C++ // C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to generate hamming code vector<int> generateHammingCode( vector<int> msgBits, int m, int r) { // Stores the Hamming Code vector<int> hammingCode(r + m); // Find positions of redundant bits for (int i = 0; i < r; ++i) { // Placing -1 at redundant bits // place to identify it later hammingCode[pow(2, i) - 1] = -1; } int j = 0; // Iterate to update the code for (int i = 0; i < (r + m); i++) { // Placing msgBits where -1 is // absent i.e., except redundant // bits all positions are msgBits if (hammingCode[i] != -1) { hammingCode[i] = msgBits[j]; j++; } } for (int i = 0; i < (r + m); i++) { // If current bit is not redundant // bit then continue if (hammingCode[i] != -1) continue; int x = log2(i + 1); int one_count = 0; // Find msg bits containing // set bit at x'th position for (int j = i + 2; j <= (r + m); ++j) { if (j & (1 << x)) { if (hammingCode[j - 1] == 1) { one_count++; } } } // Generating hamming code for // even parity if (one_count % 2 == 0) { hammingCode[i] = 0; } else { hammingCode[i] = 1; } } // Return the generated code return hammingCode; } // Function to find the hamming code // of the given message bit msgBit[] void findHammingCode(vector<int>& msgBit) { // Message bit size int m = msgBit.size(); // r is the number of redundant bits int r = 1; // Find no. of redundant bits while (pow(2, r) < (m + r + 1)) { r++; } // Generating Code vector<int> ans = generateHammingCode(msgBit, m, r); // Print the code cout << "Message bits are: "; for (int i = 0; i < msgBit.size(); i++) cout << msgBit[i] << " "; cout << "\nHamming code is: "; for (int i = 0; i < ans.size(); i++) cout << ans[i] << " "; } // Driver Code int main() { // Given message bits vector<int> msgBit = { 0, 1, 0, 1 }; // Function Call findHammingCode(msgBit); return 0; }
Time Complexity: O((M + R)2) where M is the number of bits in the input message and R is the number of redundant bits
Auxiliary Space: O(M + R) the algorithm needs space proportional to input data size (M) plus output data size (R). This is common in data manipulation algorithms like sorting or searching. Excessive memory usage can limit problem scale, so it's important to consider auxiliary space complexity alongside time complexity.
Similar Reads
C++ Programming Language C++ is a computer programming language developed by Bjarne Stroustrup as an extension of the C language. It is known for is fast speed, low level memory management and is often taught as first programming language. It provides:Hands-on application of different programming concepts.Similar syntax to
5 min read
Object Oriented Programming in C++ Object Oriented Programming - As the name suggests uses objects in programming. Object-oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism, etc. in programming. The main aim of OOP is to bind together the data and the functions that operate on them so th
5 min read
30 OOPs Interview Questions and Answers [2025 Updated] Object-oriented programming, or OOPs, is a programming paradigm that implements the concept of objects in the program. It aims to provide an easier solution to real-world problems by implementing real-world entities such as inheritance, abstraction, polymorphism, etc. in programming. OOPs concept is
15 min read
Inheritance in C++ The capability of a class to derive properties and characteristics from another class is called Inheritance. Inheritance is one of the most important features of Object-Oriented Programming in C++. In this article, we will learn about inheritance in C++, its modes and types along with the informatio
10 min read
Vector in C++ STL C++ vector is a dynamic array that stores collection of elements same type in contiguous memory. It has the ability to resize itself automatically when an element is inserted or deleted.Create a VectorBefore creating a vector, we must know that a vector is defined as the std::vector class template i
7 min read
Templates in C++ C++ template is a powerful tool that allows you to write a generic code that can work with any data type. The idea is to simply pass the data type as a parameter so that we don't need to write the same code for different data types.For example, same sorting algorithm can work for different type, so
9 min read
C++ Interview Questions and Answers (2025) C++ - the must-known and all-time favourite programming language of coders. It is still relevant as it was in the mid-80s. As a general-purpose and object-oriented programming language is extensively employed mostly every time during coding. As a result, some job roles demand individuals be fluent i
15+ min read
Operator Overloading in C++ in C++, Operator overloading is a compile-time polymorphism. It is an idea of giving special meaning to an existing operator in C++ without changing its original meaning.In this article, we will further discuss about operator overloading in C++ with examples and see which operators we can or cannot
8 min read
C++ Standard Template Library (STL) The C++ Standard Template Library (STL) is a set of template classes and functions that provides the implementation of common data structures and algorithms such as lists, stacks, arrays, sorting, searching, etc. It also provides the iterators and functors which makes it easier to work with algorith
9 min read
Map in C++ STL In C++, maps are associative containers that store data in the form of key value pairs sorted on the basis of keys. No two mapped values can have the same keys. By default, it stores data in ascending order of the keys, but this can be changes as per requirement.Example:C++#include <bits/stdc++.h
8 min read