In alcune situazioni può capitare la necessità di verificare due file, magari aventi nomi diversi e apparentemente non legati tra loro, per capire se rappresentano la stessa informazione.
Ovviamente la prima cosa che possiamo fare è verificare il loro peso, ovvero la grandezza in KB o MB che occupano i due file su disco, ma questo non è sufficiente per stabilire se effettivamente rappresentano la stessa informazione. Possiamo farlo invece abbastanza facilmente comparando i due file, anche nel caso di file binari, utilizzando un algoritmo di hashing.
Per chi non lo sapesse, un algoritmo di hashing (o di hash) è, detto in maniera semplice, un metodo di trasformazione irreversibile, con il quale una certa informazione viene trasformata in un'altra informazione.
L'informazione originaria, processata e trasformata attraverso un algoritmo di hashing, viene chiamata digest. Dal digest quindi non sarà più possibile risalire al dato da cui è stato generato.
Si tratta di algoritmi matematici molto complessi, che non verranno approfonditi in questa sede, almeno per il momento. Ne esistono di diversi tipi e complessità, ma le caratteristiche che più ci interessano sono:
- il processo non è reversibile (lo abbiamo appena detto);
- la lunghezza del digest è fissa (in funzione dell'algoritmo usato) indipendentemente dalla grandezza dell'informazione originaria;
- il digest è univoco, ovvero non esistono più informazioni originali diverse tra loro che producono lo stesso digest;
- il digest è legato all'informazione originale, ovvero alla stessa informazione originale corrisponde sempre lo stesso digest.
Questa velocissima introduzione su cosa sia un algoritmo di hashing lascia subito intendere che nel mondo informatico questi abbiano trovato una grossa applicabilità, per tanti motivi che non staremo qui a spiegare. Per adesso concentriamo la nostra attenzione sull'ultima caratteristica tra quelle elencate: alla stessa informazione originale corrisponde sempre lo stesso digest.
Potete capire che quindi un algoritmo di hashing può fare proprio al caso nostro. Nell'esempio creiamo un extension method per farlo, ma ovviamente non è strettamente necessario:
public static class Ext { public static bool IsSameFile(this string sFile1, string sFile2) { FileStream fs1 = new FileStream(sFile1, FileMode.Open); FileStream fs2 = new FileStream(sFile2, FileMode.Open); HashAlgorithm hash = HashAlgorithm.Create("MD5"); byte[] baHash1 = hash.ComputeHash(fs1); byte[] baHash2 = hash.ComputeHash(fs2); string sDigest1 = BitConverter.ToString(baHash1); string sDigest2 = BitConverter.ToString(baHash2); bool bFilesAreEqual = sDigest1.Equals(sDigest2); return bFilesAreEqual; } }
Come si vede dal codice, nel nostro semplice esempio, per verificare se due file siano effettivamente identici nel contenuto, utilizziamo due FileStream, uno per ogni file, che ci serviranno ad ospitare appunto il contenuto di questi due files.
FileStream fs1 = new FileStream(sFile1, FileMode.Open); FileStream fs2 = new FileStream(sFile2, FileMode.Open);
Una volta istanziati i due FileStream, possiamo creare una istanza della classe HashAlgoritm, che si occuperà appunto di eseguire gli hash e ottenere un digest a partire da un dato originario.
HashAlgorithm hash = HashAlgorithm.Create("MD5");
Al costruttore di questa classe basta sapere, in forma di stringa, quale algoritmo vogliamo utilizzare (tra quelli disponibili nella classe .NET).
Gli algoritmi che sono disponibili in .NET sono SHA1, MD5, SHA256, SHA384, SHA512.
La lunghezza del digest, come già spiegato prima, è fissata in funzione dell'algoritmo, e ovviamente più lungo sarà il digest da produrre, maggiore sarà il tempo necessario per produrlo.
Chiaramente con il termine "tempo" intendiamo pochi millisecondi o nel peggiore dei casi secondi, che però possono essere rilevanti in caso di operazioni batch.
Nell'esempio verrà usato l'algoritmo MD5, un algoritmo molto veloce. Con questo algoritmo, provvediamo a generare i due Digest, e quindi a confrontarli tra di loro per vedere se sono effettivamente uguali.
string sDigest1 = BitConverter.ToString(baHash1); string sDigest2 = BitConverter.ToString(baHash2); bool bFilesAreEqual = sDigest1.Equals(sDigest2);
In questo modo per comparare due file ci basterà scrivere:
string sFilePath1 = ... string sFilePath2 = ... if (sFilePath1.IsSameFile(sFilePath2)) { ... }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Effettuare il refresh dei dati di una QuickGrid di Blazor
Utilizzare Tailwind CSS all'interno di React: primi componenti
Generare velocemente pagine CRUD in Blazor con QuickGrid
Utilizzare Azure Cosmos DB con i vettori
Generare la software bill of material (SBOM) in GitHub
Utilizzare il nuovo modello GPT-4o con Azure OpenAI
Cambiare la chiave di partizionamento di Azure Cosmos DB
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
Usare i servizi di Azure OpenAI e ChatGPT in ASP.NET Core con Semantic Kernel
Sfruttare GPT-4o realtime su Azure Open AI per conversazioni vocali
Proteggere le risorse Azure con private link e private endpoints
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
I più letti di oggi
- Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
- Creare una libreria CSS universale: Cards
- Eseguire script pre e post esecuzione di un workflow di GitHub