Le varianti OLE, utilizzate dalle versioni precedenti di Visual Basic e pervasivamente in COM Automation, possono memorizzare molti tipi diversi: tipi di base come interi e float, tipi più complicati come stringhe e array e fino alle implementazioni IDispatch
e puntatori sotto forma di varianti ByRef
.Qual è l'implementazione consigliata per le varianti OLE di hashing?
Anche le varianti sono digitate debolmente: convertono il valore in un altro tipo senza avviso a seconda dell'operatore che si applica e dei tipi correnti dei valori passati all'operatore. Ad esempio, confrontando due varianti, una contenente il numero intero 1
e un'altra contenente la stringa "1"
, l'uguaglianza restituirà True
.
Quindi, supponendo che sto lavorando con varianti a livello dei dati sottostanti (ad esempio VARIANT
in C++ o TVarData
in Delphi - vale a dire la grande unione di diversi possibili valori), come devo hash varianti costantemente in modo che obbediscono il diritto regole?
Regole:
- varianti che hash diseguale deve confrontare come diseguale, sia nella selezione e l'uguaglianza diretta
- varianti che mettono a confronto come uguale sia per l'ordinamento e l'uguaglianza diretta dovrebbe hash uguale
Va bene se devo usare diversi ordinamenti e regole di confronto diretto per rendere l'hashing adatto.
Attualmente sto lavorando per normalizzare le varianti alle stringhe (se si adattano) e trattarle come stringhe, altrimenti sto lavorando con i dati della variante come se fosse un blob opaco, e hashing e confrontando i suoi byte non elaborati. Questo ha alcune limitazioni, naturalmente: i numeri 1..10
ordinano come [1, 10, 2, ... 9]
ecc. Questo è leggermente fastidioso, ma è coerente ed è pochissimo lavoro. Tuttavia, mi chiedo se esiste una pratica accettata per questo problema.
VARIANT è in realtà una struttura, che ha due parti di dati: valore e tipo. La tua richiesta di comparazione e conversione sembra prendere in considerazione solo il valore e non considera il tipo archiviato di quella struttura. L'approccio giusto è quello di considerare sempre anche il tipo archiviato. –
@Franci, penso che tu abbia perso il punto. Due varianti possono essere paragonate anche quando i loro tipi differiscono. Se le varianti sono uguali, Barry desidera che anche i loro hash siano uguali. 'Variant (1) = Variant ('1')' ==> 'hash (Variant (1)) = hash (Variant ('1'))'. –
Barry, non penso che la tua prima regola sia giusta. Ignora la possibilità di collisioni di hash, dove gli hash sono uguali ma i valori non sono affatto simili. –