feat: Add endian option to Sum hash

This commit is contained in:
WerWolv 2025-12-07 22:18:34 +01:00
parent 994df0a3a4
commit 6427f53b5a
6 changed files with 64 additions and 32 deletions

View File

@ -21,6 +21,7 @@
#include <ranges>
#include <fonts/tabler_icons.hpp>
#include <ui/widgets.hpp>
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;
}
}
}

View File

@ -17,6 +17,7 @@ add_imhex_plugin(
INCLUDES
include
LIBRARIES
ui
fonts
hashplus
)

View File

@ -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"
}

View File

@ -12,6 +12,8 @@
#include <HashFactory.h>
#include <ui/widgets.hpp>
namespace hex::plugin::hashes {
namespace {
@ -471,12 +473,21 @@ namespace hex::plugin::hashes {
u64 sum = hash.m_initialValue;
{
u64 partialSum = 0x00;
u8 progress = 0;
for (u8 byte : reader) {
sum += (byte << (8 * progress));
progress += 1;
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<int>();
m_outputSize = data.at("size").get<int>();
m_endian = data.at("endian").get<int>() == 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 {

View File

@ -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);
}

View File

@ -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;
}
}