HammingCode C++ partial functionality implementation.
HammingCode
Preknowledge
&
,|
,^
The priority of operator &
is lower than !=
in C++
,C#
(maybe).
In fact, for digit operators and logic operators:
||
< &&
< |
< ^
< &
< !=
= ==
< other logic operators
< <<
= >>
So, make sure of using parenthesis: ()
Under csi (C# script interactive):
> (5+1) & 5 != 0
(1,1): error CS0019: Operator '&' cannot be applied to operands of type 'int' and 'bool'
> 5 & (5+1) != 0
(1,1): error CS0019: Operator '&' cannot be applied to operands of type 'int' and 'bool'
> (5 & (5+1)) != 0
true
The ^ operator can be used as ! operator to binary digits by $digit ^ 1
,and as copying to binary digits by $digit ^ 0
:
Under csi:
> 0^1
1
> 1^1
0
> 0^0
0
> 1^0
1
The &
operator can be used as judging whether the number is the power of 2
.
bool isPowerOf2(int num) {return (num & (num - 1)) == 0;}
Under csi:
> bool isPowerOf2(int num) {return (num & (num - 1)) == 0;}
> isPowerOf2(8)
true
<<
Operator <<
can be used as judging whether the i-th (starts from 0) digit of a number is 1
:
bool isDigitTrue(int num, int digit) {return (1<<(digit) & num) != 0;}
Under csi:
> 1 << 6 & 0b10101001
0
> 1 << 5 & 0b10101001
32
> (1 << 5 & 0b10101001) != 0
true
> bool isDigitTrue(int num, int digit) {return (1<<(digit) & num) != 0;}
> isDigitTrue(0b10101001,5)
true
Hamming code function
n
+
k
≤
2
k
−
1
(
n
:
Raw data digitN
,
k
:
Correction digitN
)
n + k \leq 2^k - 1 (n: \text{Raw data digitN}, k: \text{Correction digitN})
n+k≤2k−1(n:Raw data digitN,k:Correction digitN)
Suppose data
:
1011
\text{Suppose data}: 1011
Suppose data:1011
D
4
=
1
,
D
3
=
0
,
D
2
=
1
,
D
1
=
1
D_4 = 1, D_3 = 0, D_2 = 1, D_1 = 1
D4=1,D3=0,D2=1,D1=1
Hamming code:
D
4
,
D
3
,
D
2
,
H
3
,
D
1
,
H
2
,
H
1
1
,
0
,
1
,
_
,
1
,
_
,
_
D_4,D_3,D_2,H_3,D_1,H_2,H_1 \\ 1,0,1,\_,1,\_,\_
D4,D3,D2,H3,D1,H2,H11,0,1,_,1,_,_
Implementation
#include "vector"
#include "string"
#include "iostream"
#include "algorithm"
//#include "bits/stdc++.h"
namespace HammingCode
{
int getCorrectionCnt(int dataSize, int correctionCnt = 0)
{
// Obtain hamming code digitN: n + k \leq 2^k - 1 (n: Raw data digitN, k: Correction digitN)
return (1 << correctionCnt) < dataSize + correctionCnt + 1 ? getCorrectionCnt(dataSize, ++correctionCnt) : correctionCnt;
}
int xorOperation(const int pos, const std::vector<int> encodedData)
{
int xorResult = 0;
// Traverse the encoded vector, operating xor operation with specific digits.
for (int i = 0; i < encodedData.size(); i++)
{
if ((pos & (i + 1)) != 0)
{
// If the corresponding digit of index is 1, do the XORs.
// Remind that the correction digit initial value is 0, which does not contribute to the XOR operation.
// Remind that the xorResult initial value is 0, which still does not contribute to the XOR operation and ensures the operation to include the correction digit.
xorResult ^= encodedData[encodedData.size() - 1 - i];
}
}
return xorResult;
}
std::vector<int> encodeData(const std::vector<int> binarydata)
{
int datalength = binarydata.size();
int correctionCnt = getCorrectionCnt(datalength);
int encodedLength = datalength + correctionCnt;
std::vector<int> encodedData(encodedLength, 0);
// Traverse the encodedData vector.
for (int i = 0, j = 0; i < encodedLength; i++)
{
// If the (i+1)-th digit is not power of 2.
if (((i + 1) & i) != 0)
{
// Copy data.
encodedData[encodedLength - 1 - i] = binarydata[datalength - 1 - (j++)];
}
}
// Traverse the correctionDigits
for (int i = 0; i < correctionCnt; i++)
{
// The correctionCode's digit position (starts from 1).
int correctionPos = 1 << i;
// The val in data vector.
int correctionDigitVal = 0;
// Traverse the encoded vector, operating xor operation with specific digits.
correctionDigitVal = xorOperation(correctionPos, encodedData);
encodedData[encodedLength - 1 - (correctionPos - 1)] = correctionDigitVal;
}
return encodedData;
}
std::vector<int> decodeDataAndCorrect(std::vector<int> encodedData)
{
int encodedLength = encodedData.size();
int correctionCnt = 0;
while ((1 << correctionCnt) < encodedLength + 1)
{
correctionCnt++;
}
int datalength = encodedLength - correctionCnt;
int errorCode = 0;
// Traverse the correctionDigits
for (int i = 0; i < correctionCnt; i++)
{
// The correctionCode's digit position (starts from 1).
int correctionPos = 1 << i;
// The val in data vector.
int xorResult = 0;
xorResult = xorOperation(correctionPos, encodedData);
// Amazing huh?
errorCode |= xorResult << i;
}
// If errorCode is not 0, correct the data.
if (errorCode != 0)
{
// The error code is the position of the error bit.
encodedData[encodedLength - 1 - (errorCode - 1)] ^= 1;
}
return encodedData;
}
}
int main()
{
std::vector<int> encodedData = HammingCode::encodeData(std::vector<int>{1, 0, 1, 0});
std::cout << "encodedData:\n";
std::for_each(encodedData.begin(), encodedData.end(), [](int val)
{ std::cout << val; });
encodedData[2] ^= 1;
std::vector<int> dataToCorrect = encodedData;
// std::cout << "dataToCorrect:\n";
// std::for_each(dataToCorrect.begin(), dataToCorrect.end(), [](int val)
// { std::cout << val; });
std::vector<int> correctedData = HammingCode::decodeDataAndCorrect(dataToCorrect);
std::cout << "\ncorrectedData:\n";
std::for_each(correctedData.begin(), correctedData.end(), [](int val)
{ std::cout << val; });
return 0;
}
可能是错的,明天再改咯。
Updated at 2024/8/5,11:39.
Fixed the length calculate algorithm in correct function.