1
0
mirror of synced 2024-11-24 15:50:16 +01:00

Fix CRC and hash calculations (#321)

* Fix CRC calculation, add more CRC parameters

Use the Boost CRC module to calculate the CRC values.
Add options for final xor value, reflectIn and reflectOut.
Fixes #320

* Cleanup Hash view combo box, add CRC8

* Use offset/size consistently

* Cleanup: unify processing data by chunks

* Change CRC algorithm back, drop boost dependency

This is mostly the original algorithm, with a few fixes and small
additions (support for reflect In / Out, final XOR value).

* Use size_t for file read size consistently
This commit is contained in:
RADICS Áron 2021-10-26 17:21:48 +02:00 committed by GitHub
parent cab1089e22
commit a6b8597f5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 365 additions and 242 deletions

View File

@ -2,6 +2,8 @@
#include <hex/views/view.hpp>
#include <array>
#include <utility>
#include <cstdio>
namespace hex {
@ -17,12 +19,24 @@ namespace hex {
void drawMenu() override;
private:
enum class HashFunctions { Crc8, Crc16, Crc32, Md5, Sha1, Sha224, Sha256, Sha384, Sha512 };
bool m_shouldInvalidate = true;
int m_currHashFunction = 0;
u64 m_hashRegion[2] = { 0 };
bool m_shouldMatchSelection = false;
static constexpr const char* HashFunctionNames[] = { "CRC16", "CRC32", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" };
static constexpr std::array hashFunctionNames {
std::pair{HashFunctions::Crc8, "CRC8"},
std::pair{HashFunctions::Crc16, "CRC16"},
std::pair{HashFunctions::Crc32, "CRC32"},
std::pair{HashFunctions::Md5, "MD5"},
std::pair{HashFunctions::Sha1, "SHA-1"},
std::pair{HashFunctions::Sha224, "SHA-224"},
std::pair{HashFunctions::Sha256, "SHA-256"},
std::pair{HashFunctions::Sha384, "SHA-384"},
std::pair{HashFunctions::Sha512, "SHA-512"},
};
};
}
}

View File

@ -146,6 +146,9 @@ namespace hex::plugin::builtin {
{ "hex.view.hashes.settings", "Settings" },
{ "hex.view.hashes.function", "Hash function" },
{ "hex.view.hashes.iv", "Initial value" },
{ "hex.view.hashes.xorout", "Final XOR value" },
{ "hex.common.reflectIn", "Reflect input" },
{ "hex.common.reflectOut", "Reflect output" },
{ "hex.view.hashes.poly", "Polynomial" },
{ "hex.view.hashes.result", "Result" },
@ -666,4 +669,4 @@ namespace hex::plugin::builtin {
});
}
}
}

View File

@ -14,8 +14,9 @@ namespace hex::crypt {
void initialize();
void exit();
u16 crc16(prv::Provider* &data, u64 offset, size_t size, u16 polynomial, u16 init);
u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init);
u16 crc8(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut);
u16 crc16(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut);
u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut);
std::array<u8, 16> md5(prv::Provider* &data, u64 offset, size_t size);
std::array<u8, 20> sha1(prv::Provider* &data, u64 offset, size_t size);
@ -54,4 +55,4 @@ namespace hex::crypt {
};
std::vector<u8> aesDecrypt(AESMode mode, KeyLength keyLength, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input);
}
}

View File

@ -15,6 +15,11 @@
#include <array>
#include <span>
#include <concepts>
#include <functional>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#if MBEDTLS_VERSION_MAJOR <= 2
@ -37,77 +42,139 @@
#endif
namespace hex::crypt {
using namespace std::placeholders;
u16 crc16(prv::Provider* &data, u64 offset, size_t size, u16 polynomial, u16 init) {
const auto table = [polynomial] {
std::array<u16, 256> table;
for (u16 i = 0; i < 256; i++) {
u16 crc = 0;
u16 c = i;
for (u16 j = 0; j < 8; j++) {
if (((crc ^ c) & 0x0001U) != 0)
crc = (crc >> 1U) ^ polynomial;
else
crc >>= 1U;
c >>= 1U;
}
table[i] = crc;
}
return table;
}();
u16 crc = init;
template<std::invocable<unsigned char*, size_t> Func>
void processDataByChunks(prv::Provider* data, u64 offset, size_t size, Func func)
{
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; offset < size; offset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
for (size_t bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const auto readSize = std::min(buffer.size(), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
for (size_t i = 0; i < readSize; i++) {
crc = (crc >> 8) ^ table[(crc ^ u16(buffer[i])) & 0x00FF];
}
func(buffer.data(), readSize);
}
return crc;
}
u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init) {
const auto table = [polynomial] {
std::array<uint32_t, 256> table = {0};
template<typename T>
T reflect(T in, std::size_t bits)
{
T out{};
for (uint32_t i = 0; i < 256; i++) {
uint32_t c = i;
for (size_t j = 0; j < 8; j++) {
if (c & 1)
c = polynomial ^ (c >> 1);
else
c >>= 1;
for(std::size_t i = 0; i < bits; i++)
{
out <<= 1;
if (in & 0b1)
out |= 1;
in >>= 1;
}
return out;
}
template<typename T>
T reflect(T in)
{
if constexpr (sizeof(T) == 1)
{
T out{in};
out = ((out & 0xf0u) >> 4) | ((out & 0x0fu) << 4);
out = ((out & 0xccu) >> 2) | ((out & 0x33u) << 2);
out = ((out & 0xaau) >> 1) | ((out & 0x55u) << 1);
return out;
}
else
{
return reflect(in, sizeof(T) *8 );
}
}
class Crc {
// use reflected algorithm, so we reflect only if refin / refout is FALSE
// mask values, 0b1 << 64 is UB, so use 0b10 << 63
public:
using calc_type = uint64_t;
Crc(int bits, calc_type polynomial, calc_type init, calc_type xorout, bool refin, bool refout) :
m_bits(bits),
m_init(init & ((0b10ull << (bits-1)) - 1)),
m_xorout(xorout & ((0b10ull << (bits-1)) - 1)),
m_refin(refin),
m_refout(refout),
table([polynomial, bits](){
auto reflectedpoly= reflect(polynomial & ((0b10ull << (bits-1)) - 1), bits);
std::array<uint64_t, 256> table = {0};
for (uint32_t i = 0; i < 256; i++) {
uint64_t c = i;
for (std::size_t j = 0; j < 8; j++) {
if (c & 0b1)
c = reflectedpoly ^ (c >> 1);
else
c >>= 1;
}
table[i] = c;
}
table[i] = c;
}
return table;
}();
return table;
}()) {
reset();
};
uint32_t c = init;
std::array<u8, 512> buffer = { 0 };
void reset() {
c = reflect(m_init, m_bits);
}
for (u64 bufferOffset = 0; offset < size; offset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
void processBytes(const unsigned char *data, std::size_t size) {
for (std::size_t i = 0; i < size; i++) {
unsigned char d;
if (m_refin)
d = data[i];
else
d = reflect(data[i]);
for (size_t i = 0; i < readSize; i++) {
c = table[(c ^ buffer[i]) & 0xFF] ^ (c >> 8);
c = table[(c ^ d) & 0xFFL] ^ (c >> 8);
}
}
return ~c;
calc_type checksum() const {
if (m_refout)
return c ^ m_xorout;
else
return reflect(c, m_bits) ^ m_xorout;
}
private:
const int m_bits;
const calc_type m_init;
const calc_type m_xorout;
const bool m_refin;
const bool m_refout;
const std::array<uint64_t, 256> table;
calc_type c;
};
template<int bits>
auto calcCrc(prv::Provider* data, u64 offset, std::size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut) {
Crc crc(bits, polynomial, init, xorout, reflectIn, reflectOut);
processDataByChunks(data, offset, size, std::bind(&Crc::processBytes, &crc, _1, _2));
return crc.checksum();
}
u16 crc8(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut) {
return calcCrc<8>(data, offset, size, polynomial, init, xorout, reflectIn, reflectOut);
}
u16 crc16(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut) {
return calcCrc<16>(data, offset, size, polynomial, init, xorout, reflectIn, reflectOut);
}
u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut) {
return calcCrc<32>(data, offset, size, polynomial, init, xorout, reflectIn, reflectOut);
}
@ -119,12 +186,7 @@ namespace hex::crypt {
mbedtls_md5_starts(&ctx);
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
mbedtls_md5_update(&ctx, buffer.data(), readSize);
}
processDataByChunks(data, offset, size, std::bind(mbedtls_md5_update, &ctx, _1, _2));
mbedtls_md5_finish(&ctx, result.data());
@ -156,12 +218,7 @@ namespace hex::crypt {
mbedtls_sha1_starts(&ctx);
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
mbedtls_sha1_update(&ctx, buffer.data(), readSize);
}
processDataByChunks(data, offset, size, std::bind(mbedtls_sha1_update, &ctx, _1, _2));
mbedtls_sha1_finish(&ctx, result.data());
@ -193,12 +250,7 @@ namespace hex::crypt {
mbedtls_sha256_starts(&ctx, true);
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
mbedtls_sha256_update(&ctx, buffer.data(), readSize);
}
processDataByChunks(data, offset, size, std::bind(mbedtls_sha256_update, &ctx, _1, _2));
mbedtls_sha256_finish(&ctx, result.data());
@ -230,12 +282,7 @@ namespace hex::crypt {
mbedtls_sha256_starts(&ctx, false);
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
mbedtls_sha256_update(&ctx, buffer.data(), readSize);
}
processDataByChunks(data, offset, size, std::bind(mbedtls_sha256_update, &ctx, _1, _2));
mbedtls_sha256_finish(&ctx, result.data());
@ -267,12 +314,7 @@ namespace hex::crypt {
mbedtls_sha512_starts(&ctx, true);
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
mbedtls_sha512_update(&ctx, buffer.data(), readSize);
}
processDataByChunks(data, offset, size, std::bind(mbedtls_sha512_update, &ctx, _1, _2));
mbedtls_sha512_finish(&ctx, result.data());
@ -304,12 +346,7 @@ namespace hex::crypt {
mbedtls_sha512_starts(&ctx, false);
std::array<u8, 512> buffer = { 0 };
for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) {
const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset);
data->read(offset + bufferOffset, buffer.data(), readSize);
mbedtls_sha512_update(&ctx, buffer.data(), readSize);
}
processDataByChunks(data, offset, size, std::bind(mbedtls_sha512_update, &ctx, _1, _2));
mbedtls_sha512_finish(&ctx, result.data());
@ -445,4 +482,4 @@ namespace hex::crypt {
return aes(type, MBEDTLS_DECRYPT, key, nonce, iv, input);
}
}
}

View File

@ -19,7 +19,7 @@ namespace hex {
this->m_hashRegion[0] = this->m_hashRegion[1] = 0;
} else {
this->m_hashRegion[0] = region.address;
this->m_hashRegion[1] = region.address + region.size;
this->m_hashRegion[1] = region.size + 1; //WARNING: get size - 1 as region size
}
this->m_shouldInvalidate = true;
}
@ -63,169 +63,237 @@ namespace hex {
ImGui::TextUnformatted("hex.view.hashes.settings"_lang);
ImGui::Separator();
if (ImGui::Combo("hex.view.hashes.function"_lang, &this->m_currHashFunction, HashFunctionNames,sizeof(HashFunctionNames) / sizeof(const char *)))
if (ImGui::BeginCombo("hex.view.hashes.function"_lang, hashFunctionNames[this->m_currHashFunction].second, 0))
{
for (int i = 0; i < hashFunctionNames.size(); i++)
{
bool is_selected = (this->m_currHashFunction == i);
if (ImGui::Selectable(hashFunctionNames[i].second, is_selected))
this->m_currHashFunction = i;
if (is_selected)
ImGui::SetItemDefaultFocus(); // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch)
}
ImGui::EndCombo();
this->m_shouldInvalidate = true;
}
size_t dataSize = provider->getSize();
if (this->m_hashRegion[1] >= provider->getBaseAddress() + dataSize)
this->m_hashRegion[1] = provider->getBaseAddress() + dataSize;
if (this->m_hashRegion[1] >= this->m_hashRegion[0]) {
switch (hashFunctionNames[this->m_currHashFunction].first) {
case HashFunctions::Crc8:
{
static int polynomial = 0x07, init = 0x0000, xorout = 0x0000;
static bool reflectIn = false, reflectOut = false;
switch (this->m_currHashFunction) {
case 0: // CRC16
{
static int polynomial = 0x8005, init = 0x0000;
ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.xorout"_lang, &xorout, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::Checkbox("hex.common.reflectIn"_lang, &reflectIn);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::NewLine();
ImGui::Checkbox("hex.common.reflectOut"_lang, &reflectOut);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
static u16 result = 0;
ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
if (this->m_shouldInvalidate)
result = crypt::crc16(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init);
ImGui::NewLine();
char buffer[sizeof(result) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%04X", result);
static u8 result = 0;
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 1: // CRC32
{
static int polynomial = 0x04C11DB7, init = 0xFFFFFFFF;
if (this->m_shouldInvalidate)
result = crypt::crc8(provider, this->m_hashRegion[0], this->m_hashRegion[1],
polynomial, init, xorout, reflectIn, reflectOut);
ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
char buffer[sizeof(result) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%02X", result);
ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::NewLine();
static u32 result = 0;
if (this->m_shouldInvalidate)
result = crypt::crc32(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init);
char buffer[sizeof(result) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%08X", result);
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 2: // MD5
{
static std::array<u8, 16> result = { 0 };
if (this->m_shouldInvalidate)
result = crypt::md5(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 3: // SHA-1
{
static std::array<u8, 20> result = { 0 };
if (this->m_shouldInvalidate)
result = crypt::sha1(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 4: // SHA-224
{
static std::array<u8, 28> result = { 0 };
if (this->m_shouldInvalidate)
result = crypt::sha224(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 5: // SHA-256
{
static std::array<u8, 32> result;
if (this->m_shouldInvalidate)
result = crypt::sha256(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 6: // SHA-384
{
static std::array<u8, 48> result;
if (this->m_shouldInvalidate)
result = crypt::sha384(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case 7: // SHA-512
{
static std::array<u8, 64> result;
if (this->m_shouldInvalidate)
result = crypt::sha512(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Crc16:
{
static int polynomial = 0x8005, init = 0x0000, xorout = 0x0000;
static bool reflectIn = false, reflectOut = false;
ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.xorout"_lang, &xorout, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::Checkbox("hex.common.reflectIn"_lang, &reflectIn);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::Checkbox("hex.common.reflectOut"_lang, &reflectOut);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::NewLine();
static u16 result = 0;
if (this->m_shouldInvalidate)
result = crypt::crc16(provider, this->m_hashRegion[0], this->m_hashRegion[1],
polynomial, init, xorout, reflectIn, reflectOut);
char buffer[sizeof(result) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%04X", result);
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Crc32:
{
static int polynomial = 0x04C11DB7, init = 0xFFFFFFFF, xorout = 0xFFFFFFFF;
static bool reflectIn = true, reflectOut = true;
ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.xorout"_lang, &xorout, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::Checkbox("hex.common.reflectIn"_lang, &reflectIn);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::Checkbox("hex.common.reflectOut"_lang, &reflectOut);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true;
ImGui::NewLine();
static u32 result = 0;
if (this->m_shouldInvalidate)
result = crypt::crc32(provider, this->m_hashRegion[0], this->m_hashRegion[1],
polynomial, init, xorout, reflectIn, reflectOut);
char buffer[sizeof(result) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%08X", result);
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Md5:
{
static std::array<u8, 16> result = { 0 };
if (this->m_shouldInvalidate)
result = crypt::md5(provider, this->m_hashRegion[0], this->m_hashRegion[1]);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Sha1:
{
static std::array<u8, 20> result = { 0 };
if (this->m_shouldInvalidate)
result = crypt::sha1(provider, this->m_hashRegion[0], this->m_hashRegion[1]);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Sha224:
{
static std::array<u8, 28> result = { 0 };
if (this->m_shouldInvalidate)
result = crypt::sha224(provider, this->m_hashRegion[0], this->m_hashRegion[1]);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Sha256:
{
static std::array<u8, 32> result;
if (this->m_shouldInvalidate)
result = crypt::sha256(provider, this->m_hashRegion[0], this->m_hashRegion[1]);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Sha384:
{
static std::array<u8, 48> result;
if (this->m_shouldInvalidate)
result = crypt::sha384(provider, this->m_hashRegion[0], this->m_hashRegion[1]);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
case HashFunctions::Sha512:
{
static std::array<u8, 64> result;
if (this->m_shouldInvalidate)
result = crypt::sha512(provider, this->m_hashRegion[0], this->m_hashRegion[1]);
char buffer[sizeof(result) * 2 + 1];
formatBigHexInt(result, buffer, sizeof(buffer));
ImGui::NewLine();
ImGui::TextUnformatted("hex.view.hashes.result"_lang);
ImGui::Separator();
ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly);
}
break;
}
this->m_shouldInvalidate = false;
}
this->m_shouldInvalidate = false;
}
ImGui::EndChild();
}
@ -236,4 +304,4 @@ namespace hex {
}
}
}