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