2010-03-19 15 views
7

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.

+1

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. –

+1

@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'))'. –

+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. –

risposta

0

I codici hash di VARIANTI uguali devono essere uguali.

Senza conoscere le regole di uguaglianza e coercizione utilizzate per testare l'uguaglianza, è difficile trovare una corretta implementazione.

+0

Sono molto familiare con il funzionamento dei codici hash.NET e Java (ho scritto compilatori sia in CLR che in JVM), ma il problema è che le varianti utilizzate in VB e Delphi non sono sicure per il tipo allo stesso modo degli oggetti polimorfici memorizzati in una posizione di tipo Oggetto in .NET o Java, o il modo in cui i valori sono sicuri per il tipo in Ruby, Python o Javascript. Ovvero, '1 ==" 1 "', o '1.Equals (" 1 ") == true', per i valori Variant di' 1' e '" 1 "'. Immagino che la risposta alla mia domanda sia "dipende" - dipende dalla semantica della lingua. –

+0

Sto contrassegnando questa risposta come è del tutto vero, per scrivere la funzione di hash che è garantita per abbinare la funzione di uguaglianza, la funzione di uguaglianza deve essere nota e ben definita. –

0

Quindi, in breve, per rendere comparabili le cose, il primo stream è un formato, una stringa o un blob comuni.

Come gestite ad es. localizzazione, ad es. la formazione di reali? Un vero confronto con una stringa contenente lo stesso reale creato in un'altra locale avrà esito negativo. O un vero testo scritto con una diversa impostazione di precisione.

Mi sembra che la definizione di equal() sia il problema, non l'hashing. Se i valori "uguali" possono essere serializzati su string (o blob) in modo diverso, l'hashing fallirà.

+0

Questo è un buon punto. Esistono due risposte potenziali: (a) utilizzare le impostazioni invarianti in modo che i codici hash siano affidabili in più istanze e locali ecc. O (b) non si preoccupi se i risultati sono coerenti all'interno di una determinata esecuzione (anche se le impostazioni potrebbero cambiare e rompere le cose in casi limite). Dato tutto ciò che è stato detto nei commenti alla mia domanda - vorrei che più di quei commenti fossero risposte effettive - posso rivedere il mio approccio e gestire i tipi individualmente, e non cercare di preservare la semantica dell'uguaglianza di tipo Delphi quando si considerano i comparatori ecc. per algoritmi. –

2

C'è una tensione incorporata nella domanda tra l'uso di una funzione di hash e i requisiti dichiarati, che devono essere convalidati rispetto all'input dell'hash. Suggerirei di tenere a mente alcune proprietà degli hash in generale: le informazioni vengono perse durante il processo di hashing e ci si può aspettare che si verifichino collisioni hash. È possibile costruire un hash perfetto senza collisioni, ma sarebbe problematico (o impossibile?) Costruire una funzione di hash perfetta se il dominio della funzione è una qualsiasi variante OLE possibile. D'altra parte, se non stiamo parlando di un perfetto hash, allora la tua prima regola viene violata.

Non conosco il contesto più ampio di ciò che stai cercando di realizzare, ma devo respingere una delle tue ipotesi: è una funzione di hash davvero quello che vuoi? Le tue esigenze potrebbero essere soddisfatte in modo abbastanza semplice se sviluppi un sistema che codifica, non hash, tutti i possibili attributi Variant OLE in modo che possano essere richiamati più tardi e confrontati con altre immagini Variant.

L'implementazione di base della conversione di Variant in una rappresentazione di stringa si sta spostando in questa direzione. Come sicuramente saprai, una Variant può contenere puntatori, doppi puntatori e array, quindi dovrai sviluppare una rappresentazione di stringa coerente di questi tipi di dati. Mi chiedo se questo approccio possa davvero essere classificato come un hash. Non stai solo persistendo gli attributi dei dati?

+0

Sto scrivendo una classe di raccolta generica per una libreria runtime. Il parametro generico potrebbe essere una variante. L'hashing perfetto non è rilevante. (In realtà, l'hashing perfetto può essere controproducente nelle piccole tabelle hash aumentando il costo di una ricerca hash fallita). –

Problemi correlati