Date: Wed, 12 Mar 2025 13:50:55 +0000
On Wed, Mar 12, 2025 at 9:54 AM Frederick Virchanza Gotham wrote:
>
> a) Feed sequential numbers followed by a salt into a hash algorithm such as MD5
Here's a constexpr implementation of the MD5 algorithm written by Wodann:
https://github.com/Wodann/constexpr-md5-cpp/blob/master/include/md5.h
I've edited it a little so that the digest is a "__uint128_t" which
means it can be used as a case label:
switch ( argc )
{
case uuid("I like chocolate!"):
break;
}
And here's how I've written a constexpr UUID generator function:
https://godbolt.org/z/cW9K4raKz
So this means we reproducible identical builds containing compile-time
128-Bit random numbers.
Next question though is whether something along the lines of this
should be in namespace std?
And here it is copy-pasted from GodBolt:
// Here's a constexpr implementation of the MD5 hash function
#include "https://raw.githubusercontent.com/healytpk/md5-constexpr/refs/heads/master/include/md5.h"
#include <source_location> // source_location
#include <string> // string
#include <type_traits> // is_unsigned
// The C++ standard library hasn't got a constexpr way
// of converting an integer to a string, hence this:
template<typename T> requires std::is_unsigned_v<T>
constexpr std::string uint_to_base10_string(T num)
{
if ( 0u == num ) return "0";
std::string s;
while ( num )
{
s.insert( s.begin(), '0' + (num % 10u) );
num /= 10u;
}
return s;
}
// We can create a 'named' or an 'unnamed' UUID
constexpr __uint128_t uuid( char const *const name = nullptr )
{
md5::details::Context c;
auto Append =
[&c](char const *const data) constexpr
{
c.append( data, md5::details::const_strlen(data) );
};
if ( nullptr == name )
{
auto const location = std::source_location::current();
Append( location.file_name() );
Append( location.function_name() );
Append( uint_to_base10_string(location.line()).c_str() );
Append( uint_to_base10_string(location.column ()).c_str() );
}
else
{
Append(name);
}
Append("This is my salt!");
return c.final();
}
// ======================= Here's some test code =========================
#include <iostream> // cout, endl
#include <ios> // hex
int main(int argc, char **argv)
{
switch ( argc )
{
case uuid("I like chocolate!"):
break;
}
constexpr auto monkey = uuid("frog");
std::cout << std::hex << (uint64_t)(monkey >> 64u) << std::endl;
}
>
> a) Feed sequential numbers followed by a salt into a hash algorithm such as MD5
Here's a constexpr implementation of the MD5 algorithm written by Wodann:
https://github.com/Wodann/constexpr-md5-cpp/blob/master/include/md5.h
I've edited it a little so that the digest is a "__uint128_t" which
means it can be used as a case label:
switch ( argc )
{
case uuid("I like chocolate!"):
break;
}
And here's how I've written a constexpr UUID generator function:
https://godbolt.org/z/cW9K4raKz
So this means we reproducible identical builds containing compile-time
128-Bit random numbers.
Next question though is whether something along the lines of this
should be in namespace std?
And here it is copy-pasted from GodBolt:
// Here's a constexpr implementation of the MD5 hash function
#include "https://raw.githubusercontent.com/healytpk/md5-constexpr/refs/heads/master/include/md5.h"
#include <source_location> // source_location
#include <string> // string
#include <type_traits> // is_unsigned
// The C++ standard library hasn't got a constexpr way
// of converting an integer to a string, hence this:
template<typename T> requires std::is_unsigned_v<T>
constexpr std::string uint_to_base10_string(T num)
{
if ( 0u == num ) return "0";
std::string s;
while ( num )
{
s.insert( s.begin(), '0' + (num % 10u) );
num /= 10u;
}
return s;
}
// We can create a 'named' or an 'unnamed' UUID
constexpr __uint128_t uuid( char const *const name = nullptr )
{
md5::details::Context c;
auto Append =
[&c](char const *const data) constexpr
{
c.append( data, md5::details::const_strlen(data) );
};
if ( nullptr == name )
{
auto const location = std::source_location::current();
Append( location.file_name() );
Append( location.function_name() );
Append( uint_to_base10_string(location.line()).c_str() );
Append( uint_to_base10_string(location.column ()).c_str() );
}
else
{
Append(name);
}
Append("This is my salt!");
return c.final();
}
// ======================= Here's some test code =========================
#include <iostream> // cout, endl
#include <ios> // hex
int main(int argc, char **argv)
{
switch ( argc )
{
case uuid("I like chocolate!"):
break;
}
constexpr auto monkey = uuid("frog");
std::cout << std::hex << (uint64_t)(monkey >> 64u) << std::endl;
}
Received on 2025-03-12 13:51:08