khash: new utility for calculating checksums

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-05-29 06:49:10 +03:00
parent 973b98117c
commit 8103af05de
5 changed files with 275 additions and 0 deletions

View file

@ -29,3 +29,4 @@ macro_optional_add_subdirectory (ksnapshot)
macro_optional_add_subdirectory (kupdatenotifier)
macro_optional_add_subdirectory (knetpkg)
macro_optional_add_subdirectory (kfirewall)
macro_optional_add_subdirectory (khash)

36
khash/CMakeLists.txt Normal file
View file

@ -0,0 +1,36 @@
project(khash)
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
include(FeatureSummary)
find_package(KDE4 4.23.0 REQUIRED)
include(KDE4Defaults)
include_directories(${KDE4_INCLUDES})
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
endif()
set(khash_SRCS
khash.cpp
)
add_executable(khash ${khash_SRCS})
target_link_libraries(khash
${KDE4_KDEUI_LIBS}
${KDE4_KFILE_LIBS}
${QT_QTNETWORK_LIBRARY}
)
install(TARGETS khash ${INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install(
PROGRAMS khash.desktop
DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR}
)
install(
FILES khash_checksum.desktop DESTINATION
${KDE4_SERVICES_INSTALL_DIR}/ServiceMenus
)

187
khash/khash.cpp Normal file
View file

@ -0,0 +1,187 @@
/* This file is part of the KDE project
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <kapplication.h>
#include <kdialog.h>
#include <khelpmenu.h>
#include <klineedit.h>
#include <kurl.h>
#include <klocale.h>
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <kdebug.h>
#include <QFile>
#include <QFileInfo>
#include <QCryptographicHash>
#include <QGridLayout>
#include <QLabel>
class KHashDialog : public KDialog
{
Q_OBJECT
public:
KHashDialog(QWidget *parent = 0);
~KHashDialog();
void setAlgorithm(const QCryptographicHash::Algorithm algorithm);
void setSource(const KUrl &source);
void start();
private:
QCryptographicHash::Algorithm m_algorithm;
KUrl m_source;
QGridLayout* m_dialoglayout;
KLineEdit* m_checksumedit;
};
KHashDialog::KHashDialog(QWidget *parent)
: KDialog(parent),
m_algorithm(QCryptographicHash::Sha1),
m_dialoglayout(nullptr),
m_checksumedit(nullptr)
{
QWidget* dialogwidget = new QWidget(this);
m_dialoglayout = new QGridLayout(dialogwidget);
QLabel* checksumlabel = new QLabel(i18n("Checksum:"), dialogwidget);
m_dialoglayout->addWidget(checksumlabel, 0, 0);
m_checksumedit = new KLineEdit(dialogwidget);
m_checksumedit->setReadOnly(true);
m_dialoglayout->addWidget(m_checksumedit, 0, 1);
// TODO: progress bar and threading
setMainWidget(dialogwidget);
}
KHashDialog::~KHashDialog()
{
}
void KHashDialog::setAlgorithm(const QCryptographicHash::Algorithm algorithm)
{
m_algorithm = algorithm;
QFontMetrics dialoglinemetric(m_checksumedit->font());
switch (algorithm) {
case QCryptographicHash::Md5: {
m_dialoglayout->setColumnMinimumWidth(1, 32 * dialoglinemetric.width('x'));
break;
}
case QCryptographicHash::Sha1: {
m_dialoglayout->setColumnMinimumWidth(1, 40 * dialoglinemetric.width('x'));
break;
}
case QCryptographicHash::Sha256: {
m_dialoglayout->setColumnMinimumWidth(1, 64 * dialoglinemetric.width('x'));
break;
}
case QCryptographicHash::Sha512: {
// NOTE: it is 128 long but don't want it to extend too much (small screens)
m_dialoglayout->setColumnMinimumWidth(1, 64 * dialoglinemetric.width('x'));
break;
}
case QCryptographicHash::KAT: {
m_dialoglayout->setColumnMinimumWidth(1, 64 * dialoglinemetric.width('x'));
break;
}
}
}
void KHashDialog::setSource(const KUrl &source)
{
m_source = source;
setCaption(KDialog::makeStandardCaption(QFileInfo(source.prettyUrl()).fileName(), this));
}
void KHashDialog::start()
{
QFile checksumfile(m_source.toLocalFile());
if (!checksumfile.open(QFile::ReadOnly)) {
m_checksumedit->setText(checksumfile.errorString());
return;
}
QCryptographicHash checksumer(m_algorithm);
if (!checksumer.addData(&checksumfile)) {
m_checksumedit->setText(i18n("Checksummer error"));
return;
}
const QByteArray checksumhex = checksumer.result().toHex();
m_checksumedit->setText(checksumhex);
}
int main(int argc, char **argv)
{
KAboutData aboutData(
"security-high", 0, ki18n("KHash"),
"1.0.0", ki18n("KDE checksum calculation utility"), KAboutData::License_GPL,
ki18n("(c) 2023 Ivailo Monev")
);
aboutData.addAuthor(ki18n("Ivailo Monev"), KLocalizedString(), "xakepa10@gmail.com");
KCmdLineArgs::init(argc, argv, &aboutData);
KCmdLineOptions options;
options.add("algorithm <algorithm>", ki18n("Checksum algorithm to use, default value"), "sha1");
options.add("+[url]", ki18n("URL to be opened"));
KCmdLineArgs::addCmdLineOptions(options);
KApplication app;
KHashDialog khashdialog;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
const QString hashtype = args->getOption("algorithm");
if (hashtype == QLatin1String("md5")) {
khashdialog.setAlgorithm(QCryptographicHash::Md5);
} else if (hashtype == QLatin1String("sha1")) {
khashdialog.setAlgorithm(QCryptographicHash::Sha1);
} else if (hashtype == QLatin1String("sha256")) {
khashdialog.setAlgorithm(QCryptographicHash::Sha256);
} else if (hashtype == QLatin1String("sha512")) {
khashdialog.setAlgorithm(QCryptographicHash::Sha512);
} else if (hashtype == QLatin1String("kat")) {
khashdialog.setAlgorithm(QCryptographicHash::KAT);
} else {
KCmdLineArgs::usageError(i18n("Algorithm must be one of: md5, sha1, sha256, sha512 or kat"));
return 1;
}
bool shouldstart = false;
for (int pos = 0; pos < args->count(); ++pos) {
khashdialog.setSource(args->url(pos));
shouldstart = true;
}
khashdialog.show();
khashdialog.setButtons(KDialog::Ok | KDialog::Close | KDialog::Help);
KHelpMenu khelpmenu(&khashdialog, &aboutData, true);
khashdialog.setButtonMenu(KDialog::Help, (QMenu*)khelpmenu.menu());
if (shouldstart) {
khashdialog.start();
}
return app.exec();
}
#include "khash.moc"

13
khash/khash.desktop Executable file
View file

@ -0,0 +1,13 @@
[Desktop Entry]
Name=KHash
GenericName=Checksum calculation utility
MimeType=all/allfiles;
Exec=khash --icon '%i' --caption '%c' %U
Icon=security-high
Type=Application
Terminal=false
StartupNotify=false
X-DocPath=khash/index.html
X-KDE-StartupNotify=false
X-DBUS-StartupType=Multi
Categories=Qt;KDE;Utility;

View file

@ -0,0 +1,38 @@
[Desktop Entry]
Actions=KHashChecksumMD5;KHashChecksumSHA1;KHashChecksumSHA256;KHashChecksumSHA512;KHashChecksumKAT;
Type=Service
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
X-KDE-Protocol=file
X-KDE-Priority=TopLevel
X-KDE-StartupNotify=false
X-KDE-Submenu=Checksum
[Desktop Action KHashChecksumMD5]
Exec=khash --algorithm=md5 %U
Icon=security-low
Name=Calculate MD5 checksum
Name[x-test]=xxCalculate MD5 checksumxx
[Desktop Action KHashChecksumSHA1]
Exec=khash --algorithm=sha1 %U
Icon=security-low
Name=Calculate SHA-1 checksum
Name[x-test]=xxCalculate SHA-1 checksumxx
[Desktop Action KHashChecksumSHA256]
Exec=khash --algorithm=sha256 %U
Icon=security-medium
Name=Calculate SHA-256 checksum
Name[x-test]=xxCalculate SHA-256 checksumxx
[Desktop Action KHashChecksumSHA512]
Exec=khash --algorithm=sha512 %U
Icon=security-high
Name=Calculate SHA-512 checksum
Name[x-test]=xxCalculate SHA-512 checksumxx
[Desktop Action KHashChecksumKAT]
Exec=khash --algorithm=kat %U
Icon=security-medium
Name=Calculate KAT checksum
Name[x-test]=xxCalculate KAT checksumxx