/*============================================================================= | | NAME | | crcCode.cpp | | DESCRIPTION | | CRC code implementation. | | AUTHOR | | Sean O'Connor | | LEGAL | | CRCDemo Version 2.1 - A Program for generating and checking CRC codes. | Copyright (C) 1999-2008 by Sean Erik O'Connor. All Rights Reserved. | | This program is free software; you can redistribute it and/or | modify it under the terms of the GNU General Public License | as published by the Free Software Foundation; version 2 | of the License. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with this program; if not, write to the Free Software | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | | The author's address is artifex@seanerikoconnor.freeservers.com | +============================================================================*/ #include "shiftRegister.h" // Binary linear feedback shift register class. #include "crcCode.h" // CRC code class. // Construct a CRC code object. CRCCode::CRCCode( char * g, unsigned long shiftRegisterPreset, bool invertParity ) : shiftRegister_( g ) , shiftRegisterPreset_( shiftRegisterPreset ) , invertParity_( invertParity ) { // For CRC codes, the number of parity bits is // n-k, which is the same as the degree of the // CRC generator polynomial. numParityBits_ = shiftRegister_.getDegreeOfGeneratorPoly() ; } CRCCode::~CRCCode() { } // Return the number of parity bytes. int CRCCode::getNumParityBytes( void ) const { return numParityBits_ / 8 ; } // Return the parity bits computed on the data in the buffer. // Parity bits are in the most significant bits of the buffer. unsigned long int CRCCode::parityBits( unsigned char * buffer, long int n ) { unsigned long int parityBits = 0L ; // Clear the shift register to its preset value. shiftRegister_.clear( shiftRegisterPreset_ ) ; // Shift message bytes into the shift register. for (long int i = 0 ; i < n ; ++i) shiftRegister_.shiftInByte( buffer[ i ] ) ; // Return the parity bits. if (invertParity_) return ~shiftRegister_.shiftRegContents() ; else return shiftRegister_.shiftRegContents() ; } // Append CRC parity bytes to the end of the buffer. // The buffer must be long enough to accomodate the // extra parity bits. Buffer length is increased // upon exit. void CRCCode::addParityToBuffer( unsigned char * buffer, long int n ) { // Compute the parity bits from the data. unsigned long int parity = parityBits( buffer, n ) ; // Initial mask is 0xFF00...00, whatever the word size. int downShiftAmount = 8 * (sizeof( parity ) - 1) ; unsigned long int mask = 0xFF << downShiftAmount ; // Append parity bits to the end of the buffer. for (int i = 0 ; i < numParityBits_ / 8 ; ++i) { buffer[ n++ ] = (unsigned char) ((mask & parity) >> downShiftAmount) ; mask >>= 8 ; downShiftAmount -= 8 ; } return ; } // Compute the shifted syndrome of the codeword. // Zero indicates we have a codeword. unsigned long int CRCCode::shiftedSyndrome( unsigned char * buffer, long int n ) { // Clear the shift register to its preset value. shiftRegister_.clear( shiftRegisterPreset_ ) ; // Invert parity bytes if necessary. if (invertParity_) { for (long int j = 0 ; j < numParityBits_ / 8 ; ++j) buffer[ (n-1)-j ] = ~buffer[ (n-1)-j ] ; } // Shift codeword bytes into the shift register. for (long int i = 0 ; i < n ; ++i) shiftRegister_.shiftInByte( buffer[ i ] ) ; // Return the shifted syndrome. // Zero means we have a codeword. return shiftRegister_.shiftRegContents() ; }