1 /*
2 This file is part of the Okteta Kasten module, made within the KDE community.
3
4 SPDX-FileCopyrightText: 2009 Friedrich W. H. Kossebau <kossebau@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8
9 #include "crc32bytearraychecksumalgorithm.hpp"
10
11 // Okteta core
12 #include <Okteta/AbstractByteArrayModel>
13 // KF
14 #include <KLocalizedString>
15
16 class Crc32LookupTable
17 {
18 public:
19 Crc32LookupTable();
20
21 public:
22 const quint32& operator[](int i) const;
23
24 private:
25 static quint32 reverseBits(quint32 bits, char bitCount);
26
27 private:
28 quint32 mTable[256];
29 };
30
Crc32LookupTable()31 Crc32LookupTable::Crc32LookupTable()
32 {
33 quint32 polynomial = 0x04c11db7;
34
35 // 256 values representing ASCII character codes.
36 for (int i = 0; i < 256; ++i) {
37 int value = reverseBits(i, 8) << 24;
38 for (int j = 0; j < 8; ++j) {
39 const bool hasMsb = (value & (1 << 31));
40 value <<= 1;
41 if (hasMsb) {
42 value ^= polynomial;
43 }
44 }
45
46 mTable[i] = reverseBits(value, 32);
47 }
48 }
49
reverseBits(quint32 bits,char bitCount)50 quint32 Crc32LookupTable::reverseBits(quint32 bits, char bitCount)
51 {
52 quint32 result = 0;
53 for (int i = 1; i <= bitCount; ++i) {
54 if (bits & 0x01) {
55 result |= (1 << (bitCount - i));
56 }
57 bits >>= 1;
58 }
59
60 return result;
61 }
62
operator [](int i) const63 inline const quint32& Crc32LookupTable::operator[](int i) const { return mTable[i]; }
64
Crc32ByteArrayChecksumAlgorithm()65 Crc32ByteArrayChecksumAlgorithm::Crc32ByteArrayChecksumAlgorithm()
66 : AbstractByteArrayChecksumAlgorithm(
67 i18nc("name of the checksum algorithm, Cyclic Redundancy Check 32", "CRC-32"))
68 {}
69
70 Crc32ByteArrayChecksumAlgorithm::~Crc32ByteArrayChecksumAlgorithm() = default;
71
parameterSet()72 AbstractByteArrayChecksumParameterSet* Crc32ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; }
73
calculateChecksum(QString * result,const Okteta::AbstractByteArrayModel * model,const Okteta::AddressRange & range) const74 bool Crc32ByteArrayChecksumAlgorithm::calculateChecksum(QString* result,
75 const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const
76 {
77 Crc32LookupTable lookupTable;
78 quint32 crcBits = 0xffffffff;
79 Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit;
80 for (Okteta::Address i = range.start(); i <= range.end(); ++i) {
81 const uchar value = (crcBits & 0xFF) ^ model->byte(i);
82 crcBits >>= 8;
83 crcBits ^= lookupTable[value];
84
85 if (i >= nextBlockEnd) {
86 nextBlockEnd += CalculatedByteCountSignalLimit;
87 emit calculatedBytes(range.localIndex(i) + 1);
88 }
89 }
90
91 crcBits ^= 0xffffffff;
92
93 *result = QStringLiteral("%1").arg(crcBits, 8, 16, QChar::fromLatin1('0'));
94
95 return true;
96 }
97