Autor Beitrag
Aggrasso
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16
Erhaltene Danke: 1



BeitragVerfasst: Fr 06.09.13 16:17 
Hallo ich hab einen fehler der mir unerklärlich ist.
Ich schreib gerade eine Hashing Class. Jetzt will ich den Code erst mal verbessern befor ich weiter mache.

So schaut es bis jetzt bei MD5, SHA1, SHA256, SHA384, SHA512, RIPEMD160, MACTripleDES aus:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
public static string Get_DataToMD5Hash(string Str_Data, bool bool_FileOrString)
        {
            string Str_Rueckmeldung = string.Empty;
            if (!string.IsNullOrEmpty(Str_Data))
            {
                try
                {
                    byte[] byte_Arry_Buffer = Encoding.Default.GetBytes(Str_Data);
                    using (MD5 MD5_Hash = new MD5CryptoServiceProvider())
                    {
                        Str_Rueckmeldung = BitConverter.ToString(MD5_Hash.ComputeHash(byte_Arry_Buffer)); // es kommt noch in else (if (bool_FileOrString == true)) ! Nur zum Test für was anders
                        M_int_Arry_HashSize[0] = MD5_Hash.HashSize;
                        if (bool_FileOrString == true)
                        {
                            if (File.Exists(Str_Data) == true)
                            {
                                using (Stream Stream_Daten = new FileStream(Str_Data, FileMode.Open, FileAccess.Read))
                                {
                                    Str_Rueckmeldung = BitConverter.ToString(MD5_Hash.ComputeHash(Stream_Daten));
                                    Stream_Daten.Close();
                                    Stream_Daten.Dispose();
                                }
                            }
                        }
                        MD5_Hash.Clear();
                    }
                }
                catch (Exception Exception_Message)
                { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
            }
            return Str_Rueckmeldung.Replace("-""").ToLower();
        }


Da mich aber das mit using (Stream Stream_Daten = new FileStream(Str_Data, FileMode.Open, FileAccess.Read)) stört,
Da ich es ja bei (MD5, SHA1, SHA256, SHA384, SHA512, RIPEMD160, MACTripleDES) drin hab.
Wollte ich es so machen:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
public static Stream Test(string Str_Data)
        {
            if ((File.Exists(Str_Data) == true) && (!string.IsNullOrEmpty(Str_Data)))
            {
                using (Stream Stream_Daten = new FileStream(Str_Data, FileMode.Open, FileAccess.Read))
                {
                    return Stream_Daten;
                }
            }
            else { return null; }
        }

public static string Get_DataToMD5Hash(string Str_Data, bool bool_FileOrString)
        {
            string Str_Rueckmeldung = string.Empty;
            if (!string.IsNullOrEmpty(Str_Data))
            {
                try
                {
                    byte[] byte_Arry_Buffer = Encoding.Default.GetBytes(Str_Data);
                    using (MD5 MD5_Hash = new MD5CryptoServiceProvider())
                    {
                        Str_Rueckmeldung = BitConverter.ToString(MD5_Hash.ComputeHash(byte_Arry_Buffer));
                        M_int_Arry_HashSize[0] = MD5_Hash.HashSize;
                        if (bool_FileOrString == true)
                        {
                            byte[] T = MD5_Hash.ComputeHash(Test(Str_Data));
                            Test(null).Close();
                            Test(null).Dispose();
                            Str_Rueckmeldung = BitConverter.ToString(T);
                        }
                        MD5_Hash.Clear();
                    }
                }
                catch (Exception Exception_Message)
                { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
            }
            return Str_Rueckmeldung.Replace("-""").ToLower();
        }


So würde ich mir eingies an Code zeilen sparen, aber ich bekomm immer die meldung ( M_Str_Exception_Message )
-> Auf eine geschlossene Datei kann nicht zugegriffen werden.

Wo hab ich jetzt den fehler ich Check es nicht !

Ich hoff ihr kommt mir eine Helfen.
Danke im vorraus.

MFG Aggrasso
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 06.09.13 16:39 
Hallo Aggrasso,

durch das Auslagern in die Methode Test wird wegen dem using-Block eben schon beim Verlassen der Methode Dispose() aufgerufen und daher ist der Stream dann schon geschlossen, wenn ComputeHash(...) ausgeführt wird.

Und die beiden Anweisungen Test(null).Close() und Test(null).Dispose() sind daher völlig fehl am Platz (d.h. überflüssig).

Abhilfe schafft entweder das Ausführen von MD5_Hash.ComputeHash innerhalb der neuen Methode (mit Übergabe von MD5 als Parameter) oder aber (wenn du dich damit schon auskennst) ein Action-Delegat als Methodenparameter. Aufruf wäre dann z.B. mittels eines Lambda-Ausdrucks
ausblenden C#-Quelltext
1:
var bytes = Test(data => MD5_Hash.ComputeHash(data));					

Die Deklaration des Delegates und dessen Verwendung bleibt dem Leser als Übung überlassen. ;-)
Aggrasso Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16
Erhaltene Danke: 1



BeitragVerfasst: Fr 06.09.13 17:07 
Hi,
das mit MD5_Hash.ComputeHash innerhalb der neuen Methode, ist fehl am Platz denn dann würde es ja nicht bei den andern funzen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
using (SHA1 SHA1_Hash = new SHA1Managed()) {...}
using (SHA256 SHA256_Hash = new SHA256Managed()) {...}
using (SHA384 SHA384_Hash = new SHA384Managed()) {...}
using (SHA512 SHA512_Hash = new SHA512Managed()) {...}
using (RIPEMD160 RIPEMD160_Hash = new RIPEMD160Managed()) {...}
using (MACTripleDES MACTripleDES_Hash = new MACTripleDES(Encoding.ASCII.GetBytes(Str_MACKey))) {...}

Get_DataToCRC16(string Str_Data, bool bool_FileOrString) {...}
Get_DataToCRC32(string Str_Data, bool bool_FileOrString) {...}


Denn zZ ist in der der Hashing Methoden der aufruf

ausblenden C#-Quelltext
1:
2:
using (Stream Stream_Daten = new FileStream(Str_Data, FileMode.Open, FileAccess.Read))
{ BitConverter.ToString(....ComputeHash(Stream_Daten)); }


Und das wollte ich ja ändern in dem ich das auslager.

Damit -> Action-Delegat als Methodenparameter <- hab ich mich soweit ich weiss noch nicht so richtig beschäftigt.

//-----------------------------------------------------------------------------------------------------

EDIT:

Ich hab es jetzt ohne "Action-Delegat" gemacht !

Über ein byte Arry als Puffer!

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
 private static byte[] M_byte_Arry_FileBuffer;  
        private static byte[] IO_Test(string Str_Data)
        {
            if ((File.Exists(Str_Data) == true) && (!string.IsNullOrEmpty(Str_Data)))
            {
                using (Stream Stream_Daten = new FileStream(Str_Data, FileMode.Open, FileAccess.Read))
                {
                    M_byte_Arry_FileBuffer = Convert_StreamToByteArry(Stream_Daten);
                }
            }
            return M_byte_Arry_FileBuffer;
        }

Dafür hab ich den Stream in ein byte Arry Converteiert

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
private static byte[] Convert_StreamToByteArry(Stream Stream_Data)
        {
            Stream_Data.Position = 0;
            byte[] byte_Arry_Buffer = new byte[Stream_Data.Length];
            for (int int_Bytes = 0; int_Bytes < Stream_Data.Length; )
            {
                int_Bytes += Stream_Data.Read(byte_Arry_Buffer,
                                              int_Bytes,
                                              Convert.ToInt32(Stream_Data.Length) - int_Bytes);
            }
            return byte_Arry_Buffer;
        }


Und hir ist jetzt der Hasher

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
public static string Get_DataToMD5Hash(string Str_Data, bool bool_FileOrString)
        {
            string Str_Rueckmeldung = string.Empty;
            if (!string.IsNullOrEmpty(Str_Data))
            {
                try
                {
                    byte[] byte_Arry_HashBuffer = Encoding.Default.GetBytes(Str_Data);
                    using (MD5 MD5_Hash = new MD5CryptoServiceProvider())
                    {
                        if (bool_FileOrString == true)
                        { Str_Rueckmeldung = BitConverter.ToString(MD5_Hash.ComputeHash(IO_Test(Str_Data))); }
                        else
                        { Str_Rueckmeldung = BitConverter.ToString(MD5_Hash.ComputeHash(byte_Arry_HashBuffer)); }
                        M_int_Arry_HashSize[0] = MD5_Hash.HashSize;
                        MD5_Hash.Clear();
                    }
                }
                catch (Exception Exception_Message)
                { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
            }
            return Str_Rueckmeldung.Replace("-""").ToLower();
        }

Das mit den "Action-Delegat" dammit muss ich mich noch mal befassen, wenn ich mehr Zeit und Nerfen hab.


MFG Aggrasso


Zuletzt bearbeitet von Aggrasso am Fr 06.09.13 18:14, insgesamt 2-mal bearbeitet
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 06.09.13 18:10 
Hallo,

doch, das funktioniert auch mit den anderen Crypto-Methoden, denn ComputeHash ist in der Basisklasse HashAlgorithm deklariert. Du mußt also dann nur HashAlgorithm als Parameter bei deiner Methode angeben (der du dann einen besseren Namen als Test geben solltest).

Edit: der Umweg über das Byte-Array ist damit also nicht nötig.

Für diesen Beitrag haben gedankt: Aggrasso
Aggrasso Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16
Erhaltene Danke: 1



BeitragVerfasst: Fr 06.09.13 18:33 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:

Edit: der Umweg über das Byte-Array ist damit also nicht nötig.


Danke Danke,
War wieder mal voll auf der leitung gestanden. ;) Ich sollte mir eien Kaffee holen :)

Und für die andern so schaut es jetzt aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
private static byte[] OpenFileForHashing(string Str_Data, HashAlgorithm HashAlgorith_HashingMode)
        {
            if ((File.Exists(Str_Data) == true) && (!string.IsNullOrEmpty(Str_Data)))
            {
                using (Stream Stream_Daten = new FileStream(Str_Data, FileMode.Open, FileAccess.Read))
                { return HashAlgorith_HashingMode.ComputeHash(Stream_Daten); }
            }
            else { return null; }
        }


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
public static string Get_DataToMD5Hash(string Str_Data, bool bool_FileOrString)
        {
            string Str_Rueckmeldung = string.Empty;
            if (!string.IsNullOrEmpty(Str_Data))
            {
                try
                {
                    byte[] byte_Arry_HashBuffer = Encoding.Default.GetBytes(Str_Data);
                    using (MD5 MD5_Hash = new MD5CryptoServiceProvider())
                    {
                        if (bool_FileOrString == true)
                        { Str_Rueckmeldung = BitConverter.ToString(OpenFileForHashing(Str_Data, MD5_Hash));  }
                        else
                        { Str_Rueckmeldung = BitConverter.ToString(MD5_Hash.ComputeHash(byte_Arry_HashBuffer)); }
                        M_int_Arry_HashSize[0] = MD5_Hash.HashSize;
                        MD5_Hash.Clear();
                    }
                }
                catch (Exception Exception_Message)
                { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
            }
            return Str_Rueckmeldung.Replace("-""").ToLower();
        }


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
public static string Get_DataToSHA1Hash(string Str_Data, bool bool_FileOrString)
        {
            string Str_Rueckmeldung = string.Empty;
            if (!string.IsNullOrEmpty(Str_Data))
            {
                try
                {
                    byte[] byte_Arry_Buffer = Encoding.Default.GetBytes(Str_Data);
                    using (SHA1 SHA1_Hash = new SHA1Managed())
                    {
                        if (bool_FileOrString == true)
                        { Str_Rueckmeldung = BitConverter.ToString(OpenFileForHashing(Str_Data, SHA1_Hash)); }
                        else
                        { Str_Rueckmeldung = BitConverter.ToString(SHA1_Hash.ComputeHash(byte_Arry_Buffer)); }
                        M_int_Arry_HashSize[2] = SHA1_Hash.HashSize;
                        SHA1_Hash.Clear();
                    }
                }
                catch (Exception Exception_Message)
                { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
            }
            return Str_Rueckmeldung.Replace("-""").ToLower();
        }


usw...

MFG Aggrasso
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 06.09.13 18:52 
Hallo nochmals,

und auch die anderen Methoden kannst du zu einer Methode vereinfachen (sofern du jeweils intern die gleichen Methoden verwendest). Entweder nicht-generisch (dann müßte man nur den new-Aufruf von außen durchführen) oder aber mittels einer generischen Methode, z.B.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
public static string Get_DataToHash<T>(string Str_Data, bool bool_FileOrString)
    where T : HashAlgorithm, new()
{
    string Str_Rueckmeldung = string.Empty;
    if (!string.IsNullOrEmpty(Str_Data))
    {
        try
        {
            byte[] byte_Arry_Buffer = Encoding.Default.GetBytes(Str_Data);
            using (T Hash = new T())
            {
                if (bool_FileOrString == true)
                { Str_Rueckmeldung = BitConverter.ToString(OpenFileForHashing(Str_Data, Hash)); }
                else
                { Str_Rueckmeldung = BitConverter.ToString(Hash.ComputeHash(byte_Arry_Buffer)); }
                M_int_Arry_HashSize[2] = Hash.HashSize;
                Hash.Clear();
            }
        }
        catch (Exception Exception_Message)
        { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
    }
    return Str_Rueckmeldung.Replace("-""").ToLower();
}

Aufruf dann einfach über
ausblenden C#-Quelltext
1:
string s = Get_DataToHash<MD5>(data, false);					


P.S. Und lass mal die "ungarische Notation" weg (Str_, bool_, byte_, ...) - liest sich nicht schön.
Und der Parameter FileOrString sagt auch wenig aus, denn man weiß nicht was nun bei Übergabe von z.B. true gilt: file or string ;-).
Aggrasso Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16
Erhaltene Danke: 1



BeitragVerfasst: Fr 06.09.13 22:17 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:


P.S. Und lass mal die "ungarische Notation" weg (Str_, bool_, byte_, ...) - liest sich nicht schön.
Und der Parameter FileOrString sagt auch wenig aus, denn man weiß nicht was nun bei Übergabe von z.B. true gilt: file or string ;-).



Deine Version ist gut nur was mir da nicht so gefällt ist, dass man die Hashing Modes manuell eingeben muss. Denn wenn ich das als Dll verpack kann man nicht naschaun was es alles gibt.
-> textBox1.Text = CryptoSystem.Hashing_Class.Get_DataToHash<SHA512Cng>("D:\\Test.txt"true); // SHA512Cng use...
Und man muss auch using System.Security.Cryptography; da einbinden von wo man es Aufruf, was mir nicht gefällt da ich ja extra eine Crypto dll schreib ;)


Da ist mir das eingefallen:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
   public enum Hashing { MD5 = 0, RIPEMD160, SHA1, SHA256, SHA384, SHA512, CRC16, CRC32 }; // Kommt noch mehr rein die nicht bei .Net dabei sind, z.b. Adler32 usw...
        public static string Get_TestHash(string Str_Data, bool bool_FileOrString, Hashing HashingMode)
        {
            string Str_Rueckmeldung = string.Empty;
            int int_Mode = (int)HashingMode;
            try
            {
                byte[] byte_Arry_Buffer = Encoding.Default.GetBytes(Str_Data);
                var SetAlgorithm = HashAlgorithm.Create();
                if (int_Mode == 0) { SetAlgorithm = new MD5Cng(); }
                if (int_Mode == 1) { SetAlgorithm = new RIPEMD160Managed(); }
                if (int_Mode == 2) { SetAlgorithm = new SHA1Cng(); }
                if (int_Mode == 3) { SetAlgorithm = new SHA256Cng(); }
                if (int_Mode == 4) { SetAlgorithm = new SHA384Cng(); }
                if (int_Mode == 5) { SetAlgorithm = new SHA512Cng(); }
                if ((int_Mode == 6) && (!string.IsNullOrEmpty(M_Str_MACTripleDES_Key))) 
                { SetAlgorithm = new MACTripleDES(Encoding.ASCII.GetBytes(M_Str_MACTripleDES_Key)); }
                // Code...
                using (HashAlgorithm HashAlgorithm_Set = SetAlgorithm)
                {
                    if (bool_FileOrString == true)
                    { Str_Rueckmeldung = BitConverter.ToString(OpenFileForHashing(Str_Data, HashAlgorithm_Set)); }
                    else
                    { Str_Rueckmeldung = BitConverter.ToString(HashAlgorithm_Set.ComputeHash(byte_Arry_Buffer)); }
                    M_int_Arry_HashSize[int_Mode] = HashAlgorithm_Set.HashSize;
                }
            }
            catch (Exception Exception_Message)
            { M_Str_Exception_Message = Exception_Message.Message.ToString(); }
            return Str_Rueckmeldung.Replace("-""").ToLower();
        }


Call:
ausblenden C#-Quelltext
1:
textBox1.Text = CryptoSystem.Hashing_Class.Get_TestHash("D:\\Test.txt"false, Hashing_Class.Hashing.MD5);					


Das mit den bool_.... usw.. hab ich so gelernt und es hat mir auch schon off den Hintern gerettet,
denn wenn der Code sehr lange und verschachtelt ist oder ( spaghetti code -> ( Obfuscator ) ) dann kann es sehr Hilfreich sein.
Oder wenn man nach 6 Wochen wieder mal an eien Alten Project weiter macht, kommt man schneller wieder rein.
Denn man weiss gleich was es für ein(e) Variable oder sonst was ist ;)

Da stimm ich dir 100% zu -> FileOrString das kommt noch weg ;)

MFG Aggrasso