Um zu vermeiden, ziehen Sie die gesamte Datei in den Speicher wie Dabblernl Lösung wollen Sie einen FileStream verwenden, wie in dieser SO Frage Computing MD5SUM of large files in C# diskutiert, aber der MD5CryptoServiceProvider können Sie keine zusätzlichen Daten am Ende hinzufügen.
So benötigen Sie einen fusionierten Strom wie folgt aus:
public class MergedStream : Stream, IDisposable
{
Stream s1;
Stream s2;
public MergedStream(Stream first, Stream second)
{
s1 = first;
s2 = second;
}
public override int Read(byte[] buffer, int offset, int count)
{
int s1count = (int)Math.Min((long)count, s1.Length - s1.Position);
int bytesRead = 0;
if (s1count > 0)
{
bytesRead += s1.Read(buffer, offset, s1count);
}
if (s1count < count)
{
bytesRead += s2.Read(buffer, offset + s1count, count - s1count);
}
return bytesRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override bool CanRead
{
get { return s1.CanRead && s2.CanRead; }
}
public override bool CanSeek
{
get { return s1.CanSeek && s2.CanSeek; }
}
public override bool CanWrite
{
get { return s1.CanWrite && s2.CanWrite; }
}
public override void Flush()
{
s1.Flush();
s2.Flush();
}
public override long Length
{
get { return s1.Length + s2.Length; }
}
public override long Position
{
get
{
return s1.Position + s2.Position;
}
set
{
throw new NotImplementedException();
}
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
void IDisposable.Dispose()
{
s1.Dispose();
s2.Dispose();
}
}
die Sie dann wie dieses Salz verwenden, können Sie Dateihash
FileStream fs = new FileStream(@"c:\text.txt", FileMode.Open);
var m = new MemoryStream(ToAnsiiBytes("SALT"), false);
var ms = new MergedStream(fs, m);
var C = hasher.ComputeHash(ms);
PrintHash(Console.Out, C);
mit ToAnsiiBytes und PrintHash nur Nutzenfunktionen als solche zu sein:
und
public static void PrintHash(TextWriter op, byte[] hash)
{
foreach (byte b in hash)
{
op.Write("{0:X2}", b);
}
}
, wenn die Datei c: \ text.txt enthält den Text toto Sie diesen Code ausführen können, um zu sehen, dass die Datei + Salz der gleiche wie der Text "totoSALT" gleich
FileStream fs = new FileStream(@"c:\text.txt", FileMode.Open);
var hasher = new MD5CryptoServiceProvider();
var A = hasher.ComputeHash(fs);
PrintHash(Console.Out, A);
Console.Out.WriteLine();
var salt = new byte[] { 0x53, 0x41, 0x4C, 0x54 };
var B = hasher.ComputeHash(ToAnsiiBytes("SALT"));
PrintHash(Console.Out, B);
Console.Out.WriteLine();
var m = new MemoryStream(ToAnsiiBytes("SALT"), false);
fs.Seek(0, SeekOrigin.Begin);
var ms = new MergedStream(fs, m);
var C = hasher.ComputeHash(ms);
PrintHash(Console.Out, C);
Console.Out.WriteLine();
HashAndPrint(Console.Out, "toto");
HashAndPrint(Console.Out, "totoSALT");
HashAndPrint(Console.Out, "SALT");
mit diesem Ausgabe
F71DBE52628A3F83A77AB494817525C6
8C4F4370C53E0C1E1AE9ACD577DDDBED
308DB2451D6580FEEB09FCF2DC1CEE19
F71DBE52628A3F83A77AB494817525C6 = toto
308DB2451D6580FEEB09FCF2DC1CEE19 = totoSALT
8C4F4370C53E0C1E1AE9ACD577DDDBED = SALT
Ich weiß nicht, ob es eine bestimmte Art und Weise zu Salz ist der Algorithmus. Sie können jedoch problemlos Ihre eigene Stream-Klasse erstellen, die das angegebene Stream-Objekt umschließt. Wenn nach den ersten paar Bytes gefragt wird, könnte das Wrapper-Objekt die Salz-Bytes geben und dann beginnen, die zugrunde liegenden Stream-Bytes zu liefern. –
In diesem Fall, mit den gegebenen Informationen, ist ein Salz unnötig und wahrscheinlich nicht möglich zu implementieren (erinnern Sie sich, dass Salze * mit * den Salzhash-Daten gespeichert werden müssen). – yfeldblum