From 6427f53b5a2300d904dedca97b31dac5c020de16 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 7 Dec 2025 22:18:34 +0100 Subject: [PATCH] feat: Add endian option to Sum hash --- .../content/views/view_data_inspector.cpp | 28 ++-------------- plugins/hashes/CMakeLists.txt | 1 + plugins/hashes/romfs/lang/en_US.json | 2 +- plugins/hashes/source/content/hashes.cpp | 31 ++++++++++++++--- plugins/ui/include/ui/widgets.hpp | 1 + plugins/ui/source/ui/widgets.cpp | 33 +++++++++++++++++++ 6 files changed, 64 insertions(+), 32 deletions(-) diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index 0dc68bfa7..75483ee19 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -21,6 +21,7 @@ #include #include +#include namespace hex::plugin::builtin { @@ -519,33 +520,8 @@ namespace hex::plugin::builtin { } void ViewDataInspector::drawEndianSetting() { - int selection = [this] { - switch (m_endian) { - default: - case std::endian::little: - return 0; - case std::endian::big: - return 1; - } - }(); - - std::array options = { - fmt::format("{}: {}", "hex.ui.common.endian"_lang, "hex.ui.common.little"_lang), - fmt::format("{}: {}", "hex.ui.common.endian"_lang, "hex.ui.common.big"_lang) - }; - - if (ImGui::SliderInt("##endian", &selection, 0, options.size() - 1, options[selection].c_str(), ImGuiSliderFlags_NoInput)) { + if (ui::endiannessSlider(m_endian)) { m_shouldInvalidate = true; - - switch (selection) { - default: - case 0: - m_endian = std::endian::little; - break; - case 1: - m_endian = std::endian::big; - break; - } } } diff --git a/plugins/hashes/CMakeLists.txt b/plugins/hashes/CMakeLists.txt index 5f0259e81..beb7edb13 100644 --- a/plugins/hashes/CMakeLists.txt +++ b/plugins/hashes/CMakeLists.txt @@ -17,6 +17,7 @@ add_imhex_plugin( INCLUDES include LIBRARIES + ui fonts hashplus ) diff --git a/plugins/hashes/romfs/lang/en_US.json b/plugins/hashes/romfs/lang/en_US.json index 16b061716..59eecd511 100644 --- a/plugins/hashes/romfs/lang/en_US.json +++ b/plugins/hashes/romfs/lang/en_US.json @@ -29,5 +29,5 @@ "hex.hashes.hash.common.refl_out": "Reflect Out", "hex.hashes.hash.common.xor_out": "XOR Out", "hex.hashes.hash.sum": "Sum", - "hex.hashes.hash.sum.fold": "Fold result" + "hex.hashes.hash.sum.fold": "Fold result down to output size" } diff --git a/plugins/hashes/source/content/hashes.cpp b/plugins/hashes/source/content/hashes.cpp index 7d12d20fd..d0a789269 100644 --- a/plugins/hashes/source/content/hashes.cpp +++ b/plugins/hashes/source/content/hashes.cpp @@ -12,6 +12,8 @@ #include +#include + namespace hex::plugin::hashes { namespace { @@ -471,12 +473,21 @@ namespace hex::plugin::hashes { u64 sum = hash.m_initialValue; - u8 progress = 0; - for (u8 byte : reader) { - sum += (byte << (8 * progress)); - progress += 1; + { + u64 partialSum = 0x00; + u8 progress = 0; + for (u8 byte : reader) { + partialSum += (byte << (8 * progress)); - progress = progress % hash.m_inputSize; + progress += 1; + if (progress == hash.m_inputSize) { + sum += hex::changeEndianness(partialSum, hash.m_inputSize, hash.m_endian); + partialSum = 0x00; + progress = 0; + } + } + + sum += hex::changeEndianness(partialSum, hash.m_inputSize, hash.m_endian); } u64 foldedSum = sum; @@ -492,6 +503,8 @@ namespace hex::plugin::hashes { } } + foldedSum = hex::changeEndianness(foldedSum, hash.m_outputSize, hash.m_endian); + std::memcpy(result.data(), &foldedSum, hash.m_outputSize); return { result.begin(), result.begin() + hash.m_outputSize }; @@ -502,6 +515,11 @@ namespace hex::plugin::hashes { ImGuiExt::InputHexadecimal("hex.hashes.hash.common.iv"_lang, &m_initialValue); ImGui::SliderInt("hex.hashes.hash.common.input_size"_lang, &m_inputSize, 1, 8, "%d", ImGuiSliderFlags_AlwaysClamp); ImGui::SliderInt("hex.hashes.hash.common.output_size"_lang, &m_outputSize, 1, 8, "%d", ImGuiSliderFlags_AlwaysClamp); + + ImGui::BeginDisabled(m_inputSize == 1); + ui::endiannessSlider(m_endian); + ImGui::EndDisabled(); + ImGui::Checkbox("hex.hashes.hash.sum.fold"_lang, &m_foldOutput); } @@ -510,6 +528,7 @@ namespace hex::plugin::hashes { result["iv"] = m_initialValue; result["size"] = m_outputSize; + result["endian"] = m_endian == std::endian::little ? 0 : 1; return result; } @@ -518,6 +537,7 @@ namespace hex::plugin::hashes { try { m_initialValue = data.at("iv").get(); m_outputSize = data.at("size").get(); + m_endian = data.at("endian").get() == 0 ? std::endian::little : std::endian::big; } catch (std::exception&) { } } @@ -526,6 +546,7 @@ namespace hex::plugin::hashes { int m_inputSize = 1; int m_outputSize = 1; bool m_foldOutput = false; + std::endian m_endian = std::endian::little; }; class HashSnefru : public ContentRegistry::Hashes::Hash { diff --git a/plugins/ui/include/ui/widgets.hpp b/plugins/ui/include/ui/widgets.hpp index fcc6aef2a..71bd8a23a 100644 --- a/plugins/ui/include/ui/widgets.hpp +++ b/plugins/ui/include/ui/widgets.hpp @@ -15,5 +15,6 @@ namespace hex::ui { }; void regionSelectionPicker(Region *region, prv::Provider *provider, RegionType *type, bool showHeader = true, bool firstEntry = false); + bool endiannessSlider(std::endian &endian); } \ No newline at end of file diff --git a/plugins/ui/source/ui/widgets.cpp b/plugins/ui/source/ui/widgets.cpp index 17cd238ae..f2669353b 100644 --- a/plugins/ui/source/ui/widgets.cpp +++ b/plugins/ui/source/ui/widgets.cpp @@ -69,4 +69,37 @@ namespace hex::ui { ImGui::EndGroup(); } + bool endiannessSlider(std::endian &endian) { + int selection = [&] { + switch (endian) { + default: + case std::endian::little: + return 0; + case std::endian::big: + return 1; + } + }(); + + std::array options = { + fmt::format("{}: {}", "hex.ui.common.endian"_lang, "hex.ui.common.little"_lang), + fmt::format("{}: {}", "hex.ui.common.endian"_lang, "hex.ui.common.big"_lang) + }; + + if (ImGui::SliderInt("##endian", &selection, 0, options.size() - 1, options[selection].c_str(), ImGuiSliderFlags_NoInput)) { + switch (selection) { + default: + case 0: + endian = std::endian::little; + break; + case 1: + endian = std::endian::big; + break; + } + + return true; + } + + return false; + } + } \ No newline at end of file