Come trovare il moltiplicatore x se x * c1 = c2, ma x * c1 causa di overflow

0

Domanda

Sto scrivendo un codice che si trova collisioni per std::hash<std::string> e cercando di invertire alcuni di calcolo dell'hash passi.

C'è una moltiplicazione in std::hash implementazione.

size_t hash2 = shift_mix(hash1) * mul;

So hash2 - dal passo precedente, anche so mul - è un valore costante = 0xc6a4a7935bd1e995UL.

shift_mix(hash1) * mul cause di overflow (hash2 / mul = 0), quindi ci vuole solo ultimi 64 bit del risultato della moltiplicazione.

Così, ho bisogno di un modo per trovare molte varianti di shift_mix(hash1) in grado di soddisfare l'uguaglianza. Qual è il modo migliore per farlo? Probabilmente in qualche modo utilizzare __int128_t?

c++ hash stdhash
2021-11-23 19:31:15
1

Migliore risposta

2

La moltiplicazione per un numero dispari modulo una potenza di due è invertibile, quindi è possibile "annullare" perfettamente, senza più opzioni che appaiono. Tuttavia, la divisione non funziona dopo il confezionamento, è necessario moltiplicare per l'inverso moltiplicativo di mul mod 264, che è 0x5f7a0ea7e59b19bd in questo caso. 0x5f7a0ea7e59b19bd * 0xc6a4a7935bd1e995 = 1.

uint64_t mul_inv = 0x5f7a0ea7e59b19bd;
uint64_t hash1 = unshift_mix(hash2 * mul_inv);
2021-11-23 19:41:58

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................