00001 00029 #include <itpp/comm/crc.h> 00030 #include <itpp/base/specmat.h> 00031 #include <itpp/base/matfunc.h> 00032 00033 00034 namespace itpp 00035 { 00036 00037 void CRC_Code::set_generator(const bvec &poly) 00038 { 00039 //it_assert(poly(0) == 1 && poly(poly.size()-1) == 1, "CRC_Code::set_polynomial: not a valid polynomial"); 00040 it_assert(poly(0) == 1, "CRC_Code::set_polynomial: not a valid polynomial"); 00041 polynomial = poly; 00042 no_parity = polynomial.size() - 1; 00043 } 00044 00046 00047 std::string crccode[18][2] = { 00048 {"CRC-4", "1 1 1 1 1"}, 00049 {"CRC-7", "1 1 0 1 0 0 0 1"}, 00050 {"CRC-8", "1 1 1 0 1 0 1 0 1"}, 00051 {"CRC-12", "1 1 0 0 0 0 0 0 0 1 1 1 1"}, 00052 {"CRC-24", "1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1"}, 00053 {"CRC-32", "1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 1 0 0 0 1 0"}, 00054 {"CCITT-4", "1 0 0 1 1"}, 00055 {"CCITT-5", "1 1 0 1 0 1"}, 00056 {"CCITT-6", "1 0 0 0 0 1 1"}, 00057 {"CCITT-16", "1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1"}, 00058 {"CCITT-32", "1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1"}, 00059 {"WCDMA-8", "1 1 0 0 1 1 0 1 1"}, 00060 {"WCDMA-12", "1 1 0 0 0 0 0 0 0 1 1 1 1"}, 00061 {"WCDMA-16", "1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1"}, 00062 {"WCDMA-24", "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1"}, 00063 {"ATM-8", "1 0 0 0 0 0 1 1 1"}, 00064 {"ANSI-16", "1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1"}, 00065 {"SDLC-16", "1 1 0 1 0 0 0 0 0 1 0 0 1 0 1 1 1"}, 00066 }; 00067 00069 00070 void CRC_Code::set_code(const std::string &code) 00071 { 00072 bvec poly; 00073 for (int i = 0; i < 18;i++) { 00074 if (crccode[i][0] == code) 00075 poly = bvec(crccode[i][1]); 00076 } 00077 00078 if ((code == "WCDMA-8") || (code == "WCDMA-12") || (code == "WCDMA-16") || (code == "WCDMA-24")) { 00079 reverse_parity = true; 00080 } 00081 00082 it_assert(poly.size() > 0, "This CRC code doesn't exist in the tables"); 00083 set_generator(poly); 00084 } 00085 00086 // Not optimized for speed! 00087 void CRC_Code::parity(const bvec &in_bits, bvec &out) const 00088 { 00089 bvec temp = concat(in_bits, zeros_b(no_parity)); 00090 00091 for (int i = 0; i < temp.size() - polynomial.size() + 1; i++) { 00092 if (temp(i) == 1) { 00093 temp.set_subvector(i, temp(i, i + no_parity) + polynomial); 00094 } 00095 } 00096 00097 out = temp(temp.size() - no_parity, temp.size() - 1); 00098 00099 if (reverse_parity) { 00100 out = reverse(out); 00101 } 00102 00103 } 00104 00105 // Not optimized for speed 00106 bool CRC_Code::check_parity(const bvec &coded_bits) const 00107 { 00108 int n = coded_bits.size(); 00109 bvec temp; 00110 00111 if (reverse_parity) { 00112 temp = concat(coded_bits.left(n - no_parity), reverse(coded_bits.right(no_parity))); 00113 } 00114 else { 00115 temp = coded_bits; 00116 } 00117 00118 for (int i = 0; i < temp.size() - polynomial.size() + 1; i++) { 00119 if (temp(i) == 1) { 00120 temp.set_subvector(i, temp(i, i + no_parity) + polynomial); 00121 } 00122 } 00123 00124 if (temp(temp.size() - no_parity, temp.size() - 1) == zeros_b(no_parity)) 00125 return true; 00126 else 00127 return false; 00128 } 00129 00130 void CRC_Code::encode(const bvec &in_bits, bvec &out) const 00131 { 00132 bvec p; 00133 parity(in_bits, p); 00134 out = concat(in_bits, p); 00135 } 00136 00137 bvec CRC_Code::encode(const bvec &in_bits) const 00138 { 00139 bvec temp; 00140 encode(in_bits, temp); 00141 return temp; 00142 } 00143 00144 bool CRC_Code::decode(const bvec &coded_bits, bvec &out) const 00145 { 00146 out = coded_bits(0, coded_bits.size() - no_parity - 1); 00147 if (check_parity(coded_bits)) { 00148 return true; 00149 } 00150 else 00151 return false; 00152 } 00153 00154 bool CRC_Code::decode(bvec &coded_bits) const 00155 { 00156 //coded_bits = coded_bits(0, coded_bits.size()-no_parity-1); <-- OLD CODE 00157 if (check_parity(coded_bits)) { 00158 return true; 00159 } 00160 else 00161 return false; 00162 } 00163 00164 } // namespace itpp
Generated on Sat Jul 9 2011 15:21:31 for IT++ by Doxygen 1.7.4