Date: Tue, 11 Mar 2025 15:47:53 +0100
AFAIK (no crypto expert), what you would want in that case is a "cryptographic hash function" (=practically non-reversible), which you use with a salt to prevent dictionary attacks.
But is it so bad, if the used name can be guessed?
Dictionary attacks are quite difficult with unique names.
Instead of a more or less random salt, one could use it as the set seed value.
And best the seed is also quite random (auto-generated) than simple numbers to prevent simple seed + simple name.
Just as example: The name then can be hierarchical in the sense of: COMPANY.PROJECT.SUBPROJECT.COMPONENT.SUBCOMPONENT.VERSION.
or whatever the caller chooses to do.
-----Ursprüngliche Nachricht-----
Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Gesendet:Di 11.03.2025 15:29
Betreff:Re: [std-proposals] Random numbers in identical builds
An:std-proposals_at_[hidden];
CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>;
On Tue, Mar 11, 2025 at 12:25 PM Sebastian Wittmeier wrote:
>
> If you want reproducible numbers,
>
> why not use a parameter to identify the specific id instead of using counters or hashing files?
>
> Seed + Parameter = uuid
>
> That would work with multiple TUs, too
Yeah that sounds like a good idea . . . I think the name should be
hashed to produce a 128-Bit number, and then encrypted, like as
follows:
https://godbolt.org/z/vx9fjYjKv
Encrypting it after getting the hash means that hackers won't be able
to brute force it by trying a dictionary of different names.
and here it is copy-pasted from GodBolt:
#include <cstdint> // uint_least32_t
#include <source_location> // source_location::current
#include <string> // string
#include <type_traits> // is_unsigned
// Here is a 128-Bit number which we use sort
// of like a 'seed' for generating UUID's
// (really it's an encryption key)
constexpr __uint128_t my_secret_key = (0x1122334455667788u |
((__uint128_t)0x99aabbccddeeff00u << 64));
// The C++ standard library hasn't got a
// constexpr way of converting a number
// 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;
}
// Hash algorithm for hashing a string
constexpr __uint128_t get_hash_of_string(char const *str)
{
// Let's pretend that this is a constexpr
// implementation of the MD5 algorithm
__uint128_t retval = 0u;
while ( *str ) retval += *str++;
return retval;
}
// Encryption algorithm for encrypting a 128-Bit number
constexpr void encrypt_one_block(__uint128_t &block, __uint128_t const &key)
{
// Let's pretend that this is a constexpr
// implementation of the AES128 algorithm
block ^= key;
}
// We can create a 'named' or an 'unnamed' UUID
constexpr __uint128_t uuid( char const *const name = nullptr )
{
__uint128_t retval = 0u;
if ( nullptr == name )
{
auto const location = std::source_location::current();
retval ^= get_hash_of_string( location.file_name() );
retval ^= get_hash_of_string( location.function_name() );
constexpr auto *to_str = &uint_to_base10_string<
std::uint_least32_t >;
retval ^= get_hash_of_string( to_str(location.column()).c_str() );
retval ^= get_hash_of_string( to_str(location.line ()).c_str() );
}
else
{
retval = get_hash_of_string(name);
}
encrypt_one_block(retval, my_secret_key);
return retval;
}
int main(void)
{
constexpr auto x = uuid();
constexpr auto y = uuid("frogs");
}
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-03-11 14:52:56