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: 2019 Lars Maier <lars.maier@tefax.net> 0005 SPDX-FileCopyrightText: 2022 Friedrich W. H. Kossebau <kossebau@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0008 */ 0009 0010 #include "crc64bytearraychecksumalgorithm.hpp" 0011 0012 // Okteta core 0013 #include <Okteta/AbstractByteArrayModel> 0014 // KF 0015 #include <KConfigGroup> 0016 #include <KLocalizedString> 0017 0018 static constexpr char Crc64ChecksumConfigGroupId[] = "CRC64"; 0019 0020 struct Crc64AlgorithmSpec 0021 { 0022 quint64 polynomial; 0023 quint64 initialValue; 0024 quint64 finalXorValue; 0025 bool inputReflected; 0026 bool outputReflected; 0027 }; 0028 0029 static const Crc64AlgorithmSpec algorithms[] = { 0030 // ECMA-182 0031 { 0x42F0E1EBA9EA3693, 0x0, 0x0, false, false }, 0032 0033 // ISO 3309 0034 { 0x000000000000001B, 0xFFFFFFFFFFFFFFFFLLU,0xFFFFFFFFFFFFFFFFLLU, true, true} 0035 0036 // Add more algorithms here 0037 }; 0038 0039 static void fillTable(quint64 poly, quint64 *table) 0040 { 0041 for (size_t i = 0; i < 256; i++) { 0042 quint64 crc = 0; 0043 for (size_t j = 0; j < 8; j++) { 0044 bool b = (i >> (7U - j)) & 0x01U; 0045 if (((crc >> 63U) != 0) != b) { 0046 crc = (crc << 1U) ^ poly; 0047 } else { 0048 crc = (crc << 1U); 0049 } 0050 } 0051 table[i] = crc; 0052 } 0053 } 0054 0055 static quint64 reflect64(quint64 x) 0056 { 0057 quint64 y = 0; 0058 for (size_t i = 0; i < 64; i++) { 0059 if ((x >> i) & 0x01U) { 0060 y |= 0x01LLU << (63 - i); 0061 } 0062 } 0063 0064 return y; 0065 } 0066 0067 static uchar reflect8(uchar x) 0068 { 0069 uchar y = 0; 0070 0071 for (size_t i = 0; i < 8; i++) { 0072 if ((x >> i) & 0x01U) { 0073 y |= 0x01U << (7 - i); 0074 } 0075 } 0076 0077 return y; 0078 } 0079 0080 Crc64ByteArrayChecksumAlgorithm::Crc64ByteArrayChecksumAlgorithm() 0081 : AbstractByteArrayChecksumAlgorithm( 0082 i18nc("name of the checksum algorithm, Cyclic Redundancy Check 64", "CRC-64"), 0083 QStringLiteral("CRC64") 0084 ) 0085 {} 0086 0087 Crc64ByteArrayChecksumAlgorithm::~Crc64ByteArrayChecksumAlgorithm() = default; 0088 0089 AbstractByteArrayChecksumParameterSet* 0090 Crc64ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } 0091 0092 void Crc64ByteArrayChecksumAlgorithm::loadConfig(const KConfigGroup& configGroup) 0093 { 0094 const KConfigGroup algorithmConfigGroup = configGroup.group(Crc64ChecksumConfigGroupId); 0095 0096 mParameterSet.loadConfig(algorithmConfigGroup); 0097 } 0098 0099 void Crc64ByteArrayChecksumAlgorithm::saveConfig(KConfigGroup& configGroup) const 0100 { 0101 KConfigGroup algorithmConfigGroup = configGroup.group(Crc64ChecksumConfigGroupId); 0102 0103 mParameterSet.saveConfig(algorithmConfigGroup); 0104 } 0105 0106 bool Crc64ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, 0107 const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0108 { 0109 const Crc64AlgorithmSpec *spec = &algorithms[static_cast<size_t>(mParameterSet.crc64Variant())]; 0110 0111 quint64 lookupTable[256]; 0112 fillTable(spec->polynomial, lookupTable); 0113 0114 quint64 crcBits = spec->initialValue; 0115 Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; 0116 for (Okteta::Address i = range.start(); i <= range.end(); ++i) { 0117 0118 uchar value = model->byte(i); 0119 if (spec->inputReflected) { 0120 value = reflect8(value); 0121 } 0122 0123 const uchar idx = (crcBits >> 56U) ^ value; 0124 crcBits = (crcBits << 8U) ^ lookupTable[idx & 0xffU]; 0125 0126 if (i >= nextBlockEnd) { 0127 nextBlockEnd += CalculatedByteCountSignalLimit; 0128 Q_EMIT calculatedBytes(range.localIndex(i) + 1); 0129 } 0130 } 0131 0132 if (spec->outputReflected) { 0133 crcBits = reflect64(crcBits); 0134 } 0135 crcBits = crcBits ^ spec->finalXorValue; 0136 0137 *result = QStringLiteral("%1").arg(crcBits, 16, 16, QChar::fromLatin1('0')); 0138 return true; 0139 } 0140 0141 #include "moc_crc64bytearraychecksumalgorithm.cpp"