El petit hashejador ha rebut queixes del seu usuari principal, jo, i clar el desenvolupador ha tingut que fer-li cas, jo mateix. Així que l'he afegit algunes funcionalitats més.
- "crea path [-r] [-desde_cero]:" crea un fitxer XML amb els Hash dels fitxers. -r indica recursiu. -desde_cero: esborra els fitxers de hashos existents. Si no es posa aquesta opció si ja existeix el fitxeret de hashos es salta la carpeta.
- "verifica path [-r] [-continua]" verifica que els fitxers tinguin el Hash correcte, -r indica recursiu, -continua no verifica els fitxers en estat VERIFICAT. Clar hem vaig trobar que el procés de verificació de moooolts fitxers triga, i volia un procés que pugui ser interromput i que continuï des d'on ho va deixar en un altra moment. La verificació guarda el fitxer de hashos cada 5GB de fitxers processat i quan acaba de verificar la carpeta.
- "resultats path [-r]" no calcula hashos, llegeix els fitxers del hasher buscant fitxers amb modificacions, errors i esborrats. -r indica recursiu. Si deixes la finestra amb el verifica fent, clar, potser et perds els errors o algo. Aleshores el resultats els ensenya.
- "actualitza path [-r]" calcula hashos per fitxers nous, esborra del fitxer de hashos els que pertanyen a fitxers esborrats, -r indica recursiu.
- "reset path [-r]" reseteja l'estat a PENDENT, -r indica recursiu. Clar, el verifica posa l'estat del fitxer a "VERIFICAT", cal doncs alguna forma de tornar a començar sense crear el fitxer de cero. Així es poden llançar verificacions en diferents dies. Primer un "reset" i després un "verifica".
Com sempre el codi, primer l'aplicació de consola, després la clase:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace Hasher
{
class Program
{
private static string ExecutablePath = "";
private static string CarpetaAProcessar = "";
private static bool Recursiu = false;
private static bool Creacio_de_cero = false;
private static string Accio = "";
private static bool Continua = false;
static void Main(string[] args)
{
string AppPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
ExecutablePath = Path.GetDirectoryName(AppPath);
try
{
if (args.Length > 0)
{
ParseParams(args);
if (CarpetaAProcessar != "")
{
if (!Directory.Exists(CarpetaAProcessar))
{
Console.WriteLine("Carpeta no trobada: " + CarpetaAProcessar);
return;
}
}
else
{
Console.WriteLine("Carpeta a processar no informada");
return;
}
switch (Accio)
{
case "crea":
crea(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - creació acabada.");
break;
case "verifica":
verifica(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - verificació acabada.");
break;
case "resultats":
resultats(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - obtenir resultats acabat.");
break;
case "actualitza":
actualitza(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - actualitza acabat.");
break;
case "reset":
reset(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - reset acabat.");
break;
default:
Console.WriteLine("Possibles parametres:");
Console.WriteLine("\"crea path [-r] [-desde_cero]\" crea un fitxer XML amb els Hash dels fitxers. "
+ "-r indica recursiu. -desde_cero: esborra els fitxers de hashos existents.");
Console.WriteLine("\"verifica path [-r] [-continua]\" verifica que els fitxers tinguin el Hash correcte, "
+ "-r indica recursiu, -continua no verifica els fitxers en estat VERIFICAT");
Console.WriteLine("\"resultats path [-r]\" no calcula hashos, llegeix els fitxers del hasher buscant "
+ " fitxers amb modificacions, -r indica recursiu");
Console.WriteLine("\"actualitza path [-r]\" calcula hashos per fitxers nous, "
+ "esborra del fitxer de hashos els que pertanyen a fitxers esborrats, -r indica recursiu");
Console.WriteLine("\"reset path [-r]\" reseteja l'estat a PENDENT, -r indica recursiu");
break;
}
}
else
{
Console.WriteLine("Possibles parametres:");
Console.WriteLine("Possibles parametres:");
Console.WriteLine("\"crea path [-r] [-desde_cero]\" crea un fitxer XML amb els Hash dels fitxers. "
+ "-r indica recursiu. -desde_cero: esborra els fitxers de hashos existents.");
Console.WriteLine("\"verifica path [-r] [-continua]\" verifica que els fitxers tinguin el Hash correcte, "
+ "-r indica recursiu, -continua no verifica els fitxers en estat VERIFICAT");
Console.WriteLine("\"resultats path [-r]\" no calcula hashos, llegeix els fitxers del hasher buscant "
+ " fitxers amb modificacions, -r indica recursiu");
Console.WriteLine("\"actualitza path [-r]\" calcula hashos per fitxers nous, "
+ "esborra del fitxer de hashos els que pertanyen a fitxers esborrats, -r indica recursiu");
Console.WriteLine("\"reset path [-r]\" reseteja l'estat a PENDENT, -r indica recursiu");
}
}
catch(Exception Err)
{
Console.WriteLine(Err.Source + " - " + Err.TargetSite + "-" + Err.Message);
}
}
private static void reset(string pPath)
{
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
Dictionary<string, clsFitxer> DicFitxers;
DicFitxers = CarregaHashos(pPath);
Console.WriteLine(ObtenirData() + " - resetejant: " + pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
objFitxer.Value.Estat = "PENDENT";
}
Save(pPath, DicFitxers);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
reset(Carpeta);
}
}
}
public static string SHA256HashFile(string sPath)
{
string sHash = "";
using (var stream = new BufferedStream(File.OpenRead(sPath), 2400000))
{
SHA256CryptoServiceProvider sha256h = new SHA256CryptoServiceProvider();
sHash = BitConverter.ToString(sha256h.ComputeHash(stream));
}
return sHash;
}
private static void actualitza(string pPath)
{
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
Dictionary<string, clsFitxer> DicFitxers;
Dictionary<string, clsFitxer> FitxersActualitzats = new Dictionary<string, clsFitxer>();
clsFitxer FitxerActualitzat = null;
DicFitxers = CarregaHashos(pPath);
DirectoryInfo dir = new DirectoryInfo(pPath);
FileInfo[] Fitxers = dir.GetFiles();
Console.WriteLine(ObtenirData() + " - Processant " + pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
try
{
if (File.Exists(pPath + "\\ " + objFitxer.Value.Nom))
{
FitxerActualitzat = new clsFitxer(objFitxer.Value.Nom,
objFitxer.Value.DataCreacio,
objFitxer.Value.DataVerificacio,
objFitxer.Value.MidaEnBytes,
objFitxer.Value.Hash,
objFitxer.Value.Estat);
FitxersActualitzats.Add(FitxerActualitzat.Nom, FitxerActualitzat);
}
}
catch (IOException e)
{
Console.WriteLine("I/O Exception: " + e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("Access Exception: " + e.Message);
}
}
foreach (FileInfo Fitxer in Fitxers)
{
if (!DicFitxers.ContainsKey(Fitxer.Name))
{
if (Fitxer.Name.ToLower() != "hasher.exe" && Fitxer.Name.ToLower() != "hasher.xml")
{
string hashValueStr = SHA256HashFile(Fitxer.FullName);
Console.WriteLine(ObtenirData() + " - hashejat: " + Fitxer.Name);
FitxerActualitzat = new clsFitxer(Fitxer.Name, DateTime.Now,
DateTime.Now,
Fitxer.Length,
hashValueStr,
"CREAT");
FitxersActualitzats.Add(Fitxer.Name, FitxerActualitzat);
}
}
}
Save(pPath, FitxersActualitzats);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
actualitza(Carpeta);
}
}
}
private static void ParseParams(string[] args)
{
for(int i = 0; i<args.Length; i++)
{
if(args[i].ToLower() == "crea")
{
Accio = "crea";
}
if (args[i].ToLower() == "verifica")
{
Accio = "verifica";
}
if (args[i].ToLower() == "resultats")
{
Accio = "resultats";
}
if (args[i].ToLower() == "actualitza")
{
Accio = "actualitza";
}
if (args[i].ToLower() == "reset")
{
Accio = "reset";
}
if (args[i].ToLower() == "-r")
{
Recursiu = true;
}
if (args[i].ToLower() == "-desde_cero")
{
Creacio_de_cero = true;
}
if (args[i].ToLower() == "-continua")
{
Continua = true;
}
if(args[i].Contains(":"))
{
CarpetaAProcessar = args[i].Replace("\\\\ ", "\\ ");
}
}
}
private static void resultats(string pPath)
{
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
Dictionary<string, clsFitxer> DicFitxers;
DicFitxers = CarregaHashos(pPath);
Console.WriteLine(ObtenirData() + " - analitzant: " + pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
if(objFitxer.Value.Estat == "NO COINCIDEIX")
{
Console.WriteLine(ObtenirData(objFitxer.Value.DataVerificacio)
+ " - fitxer amb hash canviat: " + pPath + "\\ " + objFitxer.Value.Nom);
}
else
{
if(objFitxer.Value.Estat.Contains("MIDA DIFERENT"))
{
Console.WriteLine(ObtenirData(objFitxer.Value.DataVerificacio)
+ " - fitxer amb mida diferent: " + pPath + "\\ " + objFitxer.Value.Nom);
}
else
{
if (objFitxer.Value.Estat == "ESBORRAT")
{
Console.WriteLine(ObtenirData(objFitxer.Value.DataVerificacio)
+ " - fitxer esborrat: " + pPath + "\\ " + objFitxer.Value.Nom);
}
}
}
}
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
resultats(Carpeta);
}
}
}
public static string ObtenirData(DateTime data)
{
return data.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
public static string ObtenirData()
{
return DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
public static void verifica(string pPath)
{
long GBHashejats = 0;
Console.WriteLine(ObtenirData() + " - verificant carpeta: " + pPath);
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
Dictionary<string, clsFitxer> DicFitxers;
DicFitxers = CarregaHashos(pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
if (objFitxer.Value.Estat == "VERIFICAT" && Continua)
{
Console.WriteLine(ObtenirData() + " - fitxer ja verificat anteriorment: " + objFitxer.Value.Nom);
}
else
{
try
{
if (File.Exists(pPath + "\\ " + objFitxer.Value.Nom))
{
FileInfo fiFitxer = new FileInfo(pPath + "\\ " + objFitxer.Value.Nom);
if (fiFitxer.Length != objFitxer.Value.MidaEnBytes)
{
Console.WriteLine(ObtenirData() + " - Fitxer amb mida diferent: " + fiFitxer.Name);
objFitxer.Value.Estat = "MIDA DIFERENT, actual: " + fiFitxer.Length;
}
else
{
GBHashejats += fiFitxer.Length;
string hashValueStr = SHA256HashFile(fiFitxer.FullName);
if (hashValueStr == objFitxer.Value.Hash)
{
objFitxer.Value.Estat = "VERIFICAT";
}
else
{
Console.WriteLine(ObtenirData() + " - Fitxer amb hash canviat: " + fiFitxer.Name);
objFitxer.Value.Estat = "NO COINCIDEIX";
}
if(GBHashejats > 5368709120)
{
GBHashejats = 0;
Save(pPath, DicFitxers);
}
}
}
else
{
Console.WriteLine(ObtenirData() + " - Fitxer esborrat: " + objFitxer.Value.Nom);
objFitxer.Value.Estat = "ESBORRAT";
}
objFitxer.Value.DataVerificacio = DateTime.Now;
}
catch (IOException e)
{
Console.WriteLine("I/O Exception: " + e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("Access Exception: " + e.Message);
}
}
}
Save(pPath, DicFitxers);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach(string Carpeta in Carpetes)
{
verifica(Carpeta);
}
}
}
public static Dictionary<string, clsFitxer> CarregaHashos(string pPath)
{
XmlDocument Doc = new XmlDocument();
XmlNode Fitxers;
XmlNodeList llistaDeFitxer;
XmlNode Nom;
XmlNode Hash;
XmlNode DataCreacio;
XmlNode DataVerificacio;
XmlNode Estat;
XmlNode MidaEnBytes;
clsFitxer objFitxer = null;
Dictionary<string, clsFitxer> DicFitxers = new Dictionary<string, clsFitxer>();
Doc.Load(pPath + "\\hasher.xml");
Fitxers = Doc.SelectSingleNode("descendant::fitxers");
llistaDeFitxer = Fitxers.ChildNodes;
foreach (XmlNode Fitxer in llistaDeFitxer)
{
objFitxer = new clsFitxer();
Nom = Fitxer.SelectSingleNode("descendant::nom");
Hash = Fitxer.SelectSingleNode("descendant::hash");
DataCreacio = Fitxer.SelectSingleNode("descendant::datacreacio");
DataVerificacio = Fitxer.SelectSingleNode("descendant::dataverificacio");
Estat = Fitxer.SelectSingleNode("descendant::estat");
MidaEnBytes = Fitxer.SelectSingleNode("descendant::midaenbytes");
objFitxer.Nom = Nom.InnerText;
objFitxer.Hash = Hash.InnerText;
objFitxer.DataCreacio = DateTime.ParseExact(DataCreacio.InnerText, "dd/MM/yyyy HH:mm:ss", null);
objFitxer.DataVerificacio = DateTime.ParseExact(DataVerificacio.InnerText, "dd/MM/yyyy HH:mm:ss", null);
objFitxer.Estat = Estat.InnerText;
objFitxer.MidaEnBytes = long.Parse(MidaEnBytes.InnerText);
DicFitxers.Add(objFitxer.Nom, objFitxer);
}
return DicFitxers;
}
public static void crea(string pPath)
{
bool Procesa_carpeta = false;
if (File.Exists(pPath + "\\hasher.xml"))
{
if (Creacio_de_cero)
{
File.Delete(pPath + "\\hasher.xml");
Console.WriteLine(ObtenirData() + " - Carpeta " + pPath + " amb fitxer de hashos, esborrat.");
Procesa_carpeta = true;
}
else
{
Console.WriteLine(ObtenirData() + " - Carpeta " + pPath + " amb fitxer de hashos, no procesada.");
Procesa_carpeta = false;
}
}
if (Procesa_carpeta)
{
Console.WriteLine(ObtenirData() + " - creant fitxer hashos: " + pPath);
DirectoryInfo dir = new DirectoryInfo(pPath);
FileInfo[] files = dir.GetFiles();
clsFitxer objFitxer = null;
Dictionary<string, clsFitxer> DicFitxers = new Dictionary<string, clsFitxer>();
foreach (FileInfo Fitxer in files)
{
try
{
if (Fitxer.Name.ToLower() != "hasher.exe" && Fitxer.Name.ToLower() != "hasher.xml")
{
string hashValueStr = SHA256HashFile(Fitxer.FullName);
Console.WriteLine(ObtenirData() + " - hashejat: " + Fitxer.Name);
objFitxer = new clsFitxer(Fitxer.Name,
DateTime.Now,
DateTime.Now,
Fitxer.Length,
hashValueStr,
"CREAT");
DicFitxers.Add(Fitxer.Name, objFitxer);
}
}
catch (IOException e)
{
Console.WriteLine("I/O Exception: " + e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("Access Exception: " + e.Message);
}
}
Save(pPath, DicFitxers);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
crea(Carpeta);
}
}
}
public static void Save(string pPath, Dictionary<string, clsFitxer> DicFitxers)
{
XmlDocument Doc = new XmlDocument();
XmlNode Fitxers;
XmlNode Fitxer;
XmlNode Nom;
XmlNode Hash;
XmlNode DataCreacio;
XmlNode DataVerificacio;
XmlNode Estat;
XmlNode MidaEnBytes;
Doc.LoadXml("<?xml version=\ "1.0\ " standalone=\ "yes\ "?><fitxers></fitxers>");
Fitxers = Doc.SelectSingleNode("descendant::fitxers");
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
Fitxer = Doc.CreateNode(XmlNodeType.Element, "fitxer", "");
Nom = Doc.CreateNode(XmlNodeType.Element, "nom", "");
Hash = Doc.CreateNode(XmlNodeType.Element, "hash", "");
DataCreacio = Doc.CreateNode(XmlNodeType.Element, "datacreacio", "");
DataVerificacio = Doc.CreateNode(XmlNodeType.Element, "dataverificacio", "");
Estat = Doc.CreateNode(XmlNodeType.Element, "estat", "");
MidaEnBytes = Doc.CreateNode(XmlNodeType.Element, "midaenbytes", "");
Nom.InnerText = objFitxer.Value.Nom;
Hash.InnerText = objFitxer.Value.Hash;
DataCreacio.InnerText = ObtenirData(objFitxer.Value.DataCreacio);
DataVerificacio.InnerText = ObtenirData(objFitxer.Value.DataVerificacio);
Estat.InnerText = objFitxer.Value.Estat;
MidaEnBytes.InnerText = objFitxer.Value.MidaEnBytes.ToString();
Fitxer.AppendChild(Nom);
Fitxer.AppendChild(Hash);
Fitxer.AppendChild(DataCreacio);
Fitxer.AppendChild(DataVerificacio);
Fitxer.AppendChild(Estat);
Fitxer.AppendChild(MidaEnBytes);
Fitxers.AppendChild(Fitxer);
}
Doc.Save(pPath + "\\hasher.xml");
}
}
}
Ara la clase:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hasher
{
class clsFitxer
{
public string Nom { get; set; }
public DateTime DataCreacio { get; set; }
public DateTime DataVerificacio { get; set; }
public long MidaEnBytes { get; set; }
public string Hash { get; set; }
public string Estat { get; set; }
public clsFitxer()
{
}
public clsFitxer(string pNom,
DateTime pDataCreacio,
DateTime pDataVerificacio,
long pMidaEnBytes,
string pHash,
string pEstat)
{
Nom = pNom;
DataCreacio = pDataCreacio;
DataVerificacio = pDataVerificacio;
MidaEnBytes = pMidaEnBytes;
Hash = pHash;
Estat = pEstat;
}
}
}
|