bool Qca2ByteArrayChecksumAlgorithm::calculateChecksum( QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range ) const { QCA::Hash hash( mType ); // TODO: find a way without needing to copy, perhaps by smart iterator which can return spans of original data // TODO: see if buffer size could be a value which matches the algorithm and qca2 char buffer[CalculatedByteCountSignalLimit]; int bufferLength = CalculatedByteCountSignalLimit; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; for( Okteta::Address i = range.start(); i<=range.end(); i+=CalculatedByteCountSignalLimit ) { if( range.end() < i+CalculatedByteCountSignalLimit ) bufferLength = range.end() - i + 1; model->copyTo( reinterpret_cast<Okteta::Byte*>(buffer), i, bufferLength ); hash.update( buffer, bufferLength ); if( i >= nextBlockEnd ) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes( range.localIndex(i)+1 ); } } const QByteArray hashResult = hash.final().toByteArray(); *result = QCA::arrayToHex( hashResult ); return true; }
bool Adler32ByteArrayChecksumAlgorithm::calculateChecksum( QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range ) const { quint32 a = 1; quint32 b = 0; // TODO: this is the "inefficient but straightforward implementation" from the Wikipedia entry, search for improved Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; for( Okteta::Address i = range.start(); i<=range.end(); ++i ) { a = (a + model->byte( i )) % MOD_ADLER; b = (b + a) % MOD_ADLER; if( i >= nextBlockEnd ) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes( range.localIndex(i)+1 ); } } const quint32 sum = (b << 16) | a; *result = QString::fromLatin1("%1").arg( sum, 8, 16, QChar::fromLatin1('0') ); return true; }
quint16 ModSum16ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian( const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range ) const { quint16 modSum = 0x0000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for( Okteta::Address i = range.start(); i<=range.end(); ++i ) { quint16 value = (quint16)( (quint8)(model->byte( i )) ) << 8; ++i; if( i<=range.end() ) value |= (quint16)( (quint8)(model->byte( i )) ); modSum += value; #if 0 const uchar value = (crcBits & 0xFF) + model->byte( i ); crcBits >>= 8; crcBits ^= lookupTable[value]; #endif if( i >= nextBlockEnd ) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes( range.localIndex(i)+1 ); } } return modSum; }