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;
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;
}
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;
}
}
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;
int r = 3;
int data[n] = {1, 0, 1, 1};
int encoded[n + r] = {0};
|
C++
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class hamming{
public :
string data;
int m , r = 0;
char * msg;
hamming(string data){
this ->data = data;
reverse(data.begin(),data.end());
m = data.size();
int power = 1;
while (power < (m + r + 1)){
r++;
power*=2;
}
msg = new char [m+r+1];
int curr = 0;
for ( int i = 1 ; i <= m+r ; i++){
if (i & (i-1)){
msg[i] = data[curr++];
}
else msg[i] = 'n' ;
}
setRedundantBits();
}
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(){
int bit = 0;
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++;
}
}
if (count & 1) msg[i] = '1' ;
else msg[i] = '0' ;
bit++;
}
showmsg();
}
void receiver(){
string ans = "" ;
int bit = 0;
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++;
}
}
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 (ans.find( '1' ) != string::npos){
int power = 1;
int wrongbit = 0;
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;
}
else {
cout << "correct data packet received " << endl;
}
}
};
int main(){
string data = "1011001" ;
hamming h(data);
h.receiver();
return 0;
}
|
Output
the 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
#include <math.h>
#include <stdio.h>
int input[32];
int code[32];
int ham_calc( int , int );
void solve( int input[], int );
int ham_calc( int position, int c_l)
{
int count = 0, i, j;
i = position - 1;
while (i < c_l) {
for (j = i; j < i + position; j++) {
if (code[j] == 1)
count++;
}
i = i + 2 * position;
}
if (count % 2 == 0)
return 0;
else
return 1;
}
void solve( int input[], int n)
{
int i, p_n = 0, c_l, j, k;
i = 0;
while (n > ( int ) pow (2, i) - (i + 1)) {
p_n++;
i++;
}
c_l = p_n + n;
j = k = 0;
for (i = 0; i < c_l; i++) {
if (i == (( int ) pow (2, k) - 1)) {
code[i] = 0;
k++;
}
else {
code[i] = input[j];
j++;
}
}
for (i = 0; i < p_n; i++) {
int position = ( int ) pow (2, i);
int value = ham_calc(position, c_l);
code[position - 1] = value;
}
printf ( "\nThe generated Code Word is: " );
for (i = 0; i < c_l; i++) {
printf ( "%d" , code[i]);
}
}
void main()
{
input[0] = 0;
input[1] = 1;
input[2] = 1;
input[3] = 1;
int N = 4;
solve(input, N);
}
|
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > generateHammingCode(
vector< int > msgBits, int m, int r)
{
vector< int > hammingCode(r + m);
for ( int i = 0; i < r; ++i) {
hammingCode[ pow (2, i) - 1] = -1;
}
int j = 0;
for ( int i = 0; i < (r + m); i++) {
if (hammingCode[i] != -1) {
hammingCode[i] = msgBits[j];
j++;
}
}
for ( int i = 0; i < (r + m); i++) {
if (hammingCode[i] != -1)
continue ;
int x = log2(i + 1);
int one_count = 0;
for ( int j = i + 2;
j <= (r + m); ++j) {
if (j & (1 << x)) {
if (hammingCode[j - 1] == 1) {
one_count++;
}
}
}
if (one_count % 2 == 0) {
hammingCode[i] = 0;
}
else {
hammingCode[i] = 1;
}
}
return hammingCode;
}
void findHammingCode(vector< int >& msgBit)
{
int m = msgBit.size();
int r = 1;
while ( pow (2, r) < (m + r + 1)) {
r++;
}
vector< int > ans
= generateHammingCode(msgBit, m, r);
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] << " " ;
}
int main()
{
vector< int > msgBit = { 0, 1, 0, 1 };
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.
Share your thoughts in the comments
Please Login to comment...