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