IT++ Logo Newcom Logo

crc.cpp

Go to the documentation of this file.
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
SourceForge Logo

Generated on Wed Apr 18 11:19:59 2007 for IT++ by Doxygen 1.5.2