File indexing completed on 2024-06-23 05:48:48

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2009 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "crc32bytearraychecksumalgorithm.hpp"
0010 
0011 // Okteta core
0012 #include <Okteta/AbstractByteArrayModel>
0013 // KF
0014 #include <KLocalizedString>
0015 
0016 class Crc32LookupTable
0017 {
0018 public:
0019     Crc32LookupTable();
0020 
0021 public:
0022     const quint32& operator[](int i) const;
0023 
0024 private:
0025     static quint32 reverseBits(quint32 bits, char bitCount);
0026 
0027 private:
0028     quint32 mTable[256];
0029 };
0030 
0031 Crc32LookupTable::Crc32LookupTable()
0032 {
0033     quint32 polynomial = 0x04c11db7;
0034 
0035     // 256 values representing ASCII character codes.
0036     for (int i = 0; i < 256; ++i) {
0037         int value = reverseBits(i, 8) << 24;
0038         for (int j = 0; j < 8; ++j) {
0039             const bool hasMsb = (value & (1 << 31));
0040             value <<= 1;
0041             if (hasMsb) {
0042                 value ^= polynomial;
0043             }
0044         }
0045 
0046         mTable[i] = reverseBits(value, 32);
0047     }
0048 }
0049 
0050 quint32 Crc32LookupTable::reverseBits(quint32 bits, char bitCount)
0051 {
0052     quint32 result = 0;
0053     for (int i = 1; i <= bitCount; ++i) {
0054         if (bits & 0x01) {
0055             result |= (1 << (bitCount - i));
0056         }
0057         bits >>= 1;
0058     }
0059 
0060     return result;
0061 }
0062 
0063 inline const quint32& Crc32LookupTable::operator[](int i) const { return mTable[i]; }
0064 
0065 Crc32ByteArrayChecksumAlgorithm::Crc32ByteArrayChecksumAlgorithm()
0066     : AbstractByteArrayChecksumAlgorithm(
0067         i18nc("name of the checksum algorithm, Cyclic Redundancy Check 32", "CRC-32"),
0068         QStringLiteral("CRC32")
0069       )
0070 {}
0071 
0072 Crc32ByteArrayChecksumAlgorithm::~Crc32ByteArrayChecksumAlgorithm() = default;
0073 
0074 AbstractByteArrayChecksumParameterSet* Crc32ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; }
0075 
0076 bool Crc32ByteArrayChecksumAlgorithm::calculateChecksum(QString* result,
0077                                                         const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const
0078 {
0079     Crc32LookupTable lookupTable;
0080     quint32 crcBits = 0xffffffff;
0081     Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit;
0082     for (Okteta::Address i = range.start(); i <= range.end(); ++i) {
0083         const uchar value = (crcBits & 0xFF) ^ model->byte(i);
0084         crcBits >>= 8;
0085         crcBits ^= lookupTable[value];
0086 
0087         if (i >= nextBlockEnd) {
0088             nextBlockEnd += CalculatedByteCountSignalLimit;
0089             Q_EMIT calculatedBytes(range.localIndex(i) + 1);
0090         }
0091     }
0092 
0093     crcBits ^= 0xffffffff;
0094 
0095     *result = QStringLiteral("%1").arg(crcBits, 8, 16, QChar::fromLatin1('0'));
0096 
0097     return true;
0098 }
0099 
0100 #include "moc_crc32bytearraychecksumalgorithm.cpp"