2017-05-04 2 views
4

Ich schreibe eine API, die es Benutzern ermöglicht, Dateien (Bild, Video, etc) hochzuladen. Ich verwende einen SHA-1-Hash, um sicherzustellen, dass die gleiche Datei nicht mehrfach hochgeladen wird. Früher haben wir nur kleinere Dateien erlaubt, also habe ich sie in ein Byte-Array gelesen und Hashing, aber jetzt erlauben wir größere Dateien, also verwende ich einen Dateistream. Das Problem ist, dass der SHA-1-Algorithmus einen anderen Hash zurückgibt. Ich muss herausfinden, wie man unabhängig von der Methode den gleichen Hash erhält, selbst wenn ich das Byte-Array in einen Dateistrom oder so etwas verwandeln muss. Ich habe jedoch versucht, das Byte-Array in eine temporäre Datei zu schreiben und es einzulesen, und es gibt den gleichen Hash wie das Byte-Array zurück. Hier ist ein Beispiel Konsolenanwendung, die zeigt, was ich tue:SHA-1 Hasse ein Bytearray gegen einen Datenstrom

static void Main(string[] args) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test.png"; 
    var bytes = File.ReadAllBytes(file); 
    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Sha1HashFile(bytes)); // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80 
     Console.WriteLine(Sha1HashFile(stream)); // Returns DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 
     Console.WriteLine(Sha1HashFile2(bytes)); // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80 
    } 

    Console.Read(); 
} 

public static string Sha1HashFile(byte[] file) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(Stream stream) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile2(byte[] bytes) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png"; 
    File.WriteAllBytes(file, bytes); 
    return Sha1HashFile(File.OpenRead(file)); 
} 

ich auch versucht habe, nur die Byte-Array in einen MemoryStream mit new MemoryStream(bytes) aber das hat nicht funktioniert. Es scheint, als wenn ich die Datei in einem Byte-Array habe, kann sie nicht zurückgestellt werden.

EDIT:

ich einige Code aus meinem Beispiel entfernt, weil ich dachte MD5 arbeitete. Hier ist der Originalcode, den ich zum Testen verwendet habe:

static void Main(string[] args) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test.png"; 
    var bytes = File.ReadAllBytes(file); 
    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Md5HashFile(bytes)); 
     Console.WriteLine(Md5HashFile(stream)); 
     Console.WriteLine(Sha1HashFile(bytes)); 
     Console.WriteLine(Sha1HashFile(stream)); 
     Console.WriteLine(Sha1HashFile2(bytes)); 
    } 

    Console.Read(); 
} 

public static string Md5HashFile(byte[] file) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     return BitConverter.ToString(md5.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(byte[] file) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Md5HashFile(Stream stream) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(Stream stream) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile2(byte[] bytes) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png"; 
    File.WriteAllBytes(file, bytes); 
    return Sha1HashFile(File.OpenRead(file)); 
} 

Siehe die Antwort unten für die Erklärung des Problems.

+2

Ist der Code wie in Ihrer Frage der tatsächliche echte Code dargestellt? Haben Sie versucht, den Code genau wie hier beschrieben auszuführen? Denn das Codebeispiel in Ihrer Frage ist in Ordnung und erzeugt keine anderen Hashes ... – elgonzo

+1

Außerdem ist der zweite Hash, den Sie auflisten, der eines leeren Streams. –

+0

Es ist möglich, dass der Stream einige Präambelbytes überspringt, nehme ich an. Es ist unwahrscheinlich, aber das ist das Beste, was ich mir vorstellen kann. Können Sie die ersten 3-4 Bytes des Streams im Vergleich zu den ersten 3-4 Bytes Ihres Arrays überprüfen? Sind sie identisch? – Amy

Antwort

5

Das Problem ist, dass der Stream bis zum Ende gelesen wird, wenn der erste Weg hasht. Das verursacht, dass der zweite Hash falsch ist. Aus diesem Grund muss ich entweder einen Stream für den zweiten Hash erneut öffnen oder den Stream an den Anfang zurückspulen, bevor der zweite Hash erfolgt. Hier ist die Lösung:

static void Main(string[] args) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test.png"; 
    var bytes = File.ReadAllBytes(file); 
    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Md5HashFile(bytes)); 
     Console.WriteLine(Md5HashFile(stream)); 
    } 

    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Sha1HashFile(bytes)); 
     Console.WriteLine(Sha1HashFile(stream)); 
     Console.WriteLine(Sha1HashFile2(bytes)); 
    } 

    Console.Read(); 
} 

public static string Md5HashFile(byte[] file) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     return BitConverter.ToString(md5.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(byte[] file) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Md5HashFile(Stream stream) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(Stream stream) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile2(byte[] bytes) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png"; 
    File.WriteAllBytes(file, bytes); 
    return Sha1HashFile(File.OpenRead(file)); 
} 
Verwandte Themen