Autor Beitrag
Chiyoko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# / C (VS 2019)
BeitragVerfasst: Do 01.03.12 13:43 
Huhu,

nun mein Titel beschreibt die Lage nicht ganz richtig.

Ich habe mehrere Listviews und deren Inhalte sollen auf doppelte Daten überprueft werden.
Dazu kommt eine Hashtable in Frage.

Problem 1: Ich bekomme zwar alle Namen oder Checksummen heraus, allerdings werden einige Listeneinträge nur einmal auf gezaehlt.
( Bsp:
- Piccolo
- Piccolo
- Son Goku
- Son Gohan
- Son Gohan

Woher kommt den nun Son Goku, es existieren keine 2 Dateien?
)


Problem 2: Geschwindigkeit, das berechnen der Hash summe dauert...(im ersten Beispiel) und
Problem 3: Im Beispiel 1 bekomme ich manchmal eine OutOfMemory Exception (2GB beschränkung?...habe nur keine 2GB daten)

2 Versuche(ich habe noch weitaus mehr versucht, die beiden sind aber am logischten...).
Ich hoffe , ihr seht da einigermassen durch.Alles an Code aufzulisten würde den Umfang etwas sprengen und ist auch nicht sinnvoll.

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:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
    public class CRC32
    {
// aus einem Forum im Netz...
        #region CRC-Tabelle
        private static readonly UInt32[] CRCTable =
        {        
            0x000000000x770730960xee0e612c0x990951ba0x076dc419,
            0x706af48f0xe963a5350x9e6495a30x0edb88320x79dcb8a4,
            0xe0d5e91e0x97d2d9880x09b64c2b0x7eb17cbd0xe7b82d07,        
            0x90bf1d910x1db710640x6ab020f20xf3b971480x84be41de,
            0x1adad47d0x6ddde4eb0xf4d4b5510x83d385c70x136c9856,
            0x646ba8c00xfd62f97a0x8a65c9ec0x14015c4f0x63066cd9,             
            0xfa0f3d630x8d080df50x3b6e20c80x4c69105e0xd56041e4,             
            0xa26771720x3c03e4d10x4b04d4470xd20d85fd0xa50ab56b,             
            0x35b5a8fa0x42b2986c0xdbbbc9d60xacbcf9400x32d86ce3,             
            0x45df5c750xdcd60dcf0xabd13d590x26d930ac0x51de003a,             
            0xc8d751800xbfd061160x21b4f4b50x56b3c4230xcfba9599,             
            0xb8bda50f0x2802b89e0x5f0588080xc60cd9b20xb10be924,             
            0x2f6f7c870x58684c110xc1611dab0xb6662d3d0x76dc4190,             
            0x01db71060x98d220bc0xefd5102a0x71b185890x06b6b51f,             
            0x9fbfe4a50xe8b8d4330x7807c9a20x0f00f9340x9609a88e,             
            0xe10e98180x7f6a0dbb0x086d3d2d0x91646c970xe6635c01,             
            0x6b6b51f40x1c6c61620x856530d80xf262004e0x6c0695ed,             
            0x1b01a57b0x8208f4c10xf50fc4570x65b0d9c60x12b7e950,             
            0x8bbeb8ea0xfcb9887c0x62dd1ddf0x15da2d490x8cd37cf3,             
            0xfbd44c650x4db261580x3ab551ce0xa3bc00740xd4bb30e2,             
            0x4adfa5410x3dd895d70xa4d1c46d0xd3d6f4fb0x4369e96a,             
            0x346ed9fc0xad6788460xda60b8d00x44042d730x33031de5,             
            0xaa0a4c5f0xdd0d7cc90x5005713c0x270241aa0xbe0b1010,             
            0xc90c20860x5768b5250x206f85b30xb966d4090xce61e49f,             
            0x5edef90e0x29d9c9980xb0d098220xc7d7a8b40x59b33d17,             
            0x2eb40d810xb7bd5c3b0xc0ba6cad0xedb883200x9abfb3b6,             
            0x03b6e20c0x74b1d29a0xead547390x9dd277af0x04db2615,             
            0x73dc16830xe3630b120x94643b840x0d6d6a3e0x7a6a5aa8,             
            0xe40ecf0b0x9309ff9d0x0a00ae270x7d079eb10xf00f9344,             
            0x8708a3d20x1e01f2680x6906c2fe0xf762575d0x806567cb,             
            0x196c36710x6e6b06e70xfed41b760x89d32be00x10da7a5a,             
            0x67dd4acc0xf9b9df6f0x8ebeeff90x17b7be430x60b08ed5,             
            0xd6d6a3e80xa1d1937e0x38d8c2c40x4fdff2520xd1bb67f1,
            0xa6bc57670x3fb506dd0x48b2364b0xd80d2bda0xaf0a1b4c,             
            0x36034af60x41047a600xdf60efc30xa867df550x316e8eef,             
            0x4669be790xcb61b38c0xbc66831a0x256fd2a00x5268e236,             
            0xcc0c77950xbb0b47030x220216b90x5505262f0xc5ba3bbe,             
            0xb2bd0b280x2bb45a920x5cb36a040xc2d7ffa70xb5d0cf31,             
            0x2cd99e8b0x5bdeae1d0x9b64c2b00xec63f2260x756aa39c,             
            0x026d930a0x9c0906a90xeb0e363f0x720767850x05005713,             
            0x95bf4a820xe2b87a140x7bb12bae0x0cb61b380x92d28e9b,             
            0xe5d5be0d0x7cdcefb70x0bdbdf210x86d3d2d40xf1d4e242,             
            0x68ddb3f80x1fda836e0x81be16cd0xf6b9265b0x6fb077e1,             
            0x18b747770x88085ae60xff0f6a700x66063bca0x11010b5c,             
            0x8f659eff0xf862ae690x616bffd30x166ccf450xa00ae278,             
            0xd70dd2ee0x4e0483540x3903b3c20xa76726610xd06016f7,             
            0x4969474d0x3e6e77db0xaed16a4a0xd9d65adc0x40df0b66,             
            0x37d83bf00xa9bcae530xdebb9ec50x47b2cf7f0x30b5ffe9,             
            0xbdbdf21c0xcabac28a0x53b393300x24b4a3a60xbad03605,             
            0xcdd706930x54de57290x23d967bf0xb3667a2e0xc4614ab8,             
            0x5d681b020x2a6f2b940xb40bbe370xc30c8ea10x5a05df1b,             
            0x2d02ef8d           
        };
        #endregion

        /// <summary>
        /// Berechnet die CRC32 Checksumme einer angegebenen Datei
        /// </summary>
        /// <param name="filePath">Datei, deren Checksumme berechnet werden soll</param>
        /// <returns>Die CRC32 Checksumme als String</returns>
        public static string calculateChecksum(string filePath)
        {
            byte[] file = File.ReadAllBytes(filePath);
            UInt32 CRCVal = 0xffffffff;

            for (int i = 0; i < file.Length; i++)
            {
                CRCVal = (CRCVal >> 8) ^ CRCTable[(CRCVal & 0xff) ^ file[i]];
            }

            CRCVal ^= 0xffffffff;
            byte[] Checksum = new byte[4];

            Checksum[0] = (byte)(CRCVal >> 24);
            Checksum[1] = (byte)(CRCVal >> 16);
            Checksum[2] = (byte)(CRCVal >> 8);
            Checksum[3] = (byte)(CRCVal);

            string crcHash = BitConverter.ToString(Checksum).ToLower().Replace("-""");
            return crcHash;
        }
    }


// und in der eigendlichen Funktion dann die Checksumme berechnen

            int r = checkedListview.Items.Count;

            List<string> checksummen = new List<string>();
            List<string> tempItemnamen = new List<string>(r);
            List<string> tempPfade = new List<string>(r);

            for (int i = 0; i < r; i++)
            {
                tempItemnamen.Add(checkedListview.Items[i].Text);
                tempPfade.Add(checkedListview.Items[i].SubItems[3].Text);
                checksummen.Add(CRC32.calculateChecksum(tempPfade[i]));
            }


// und nach doppelten Einträgen durchsuchen,...und hier liegt das eigendliche Problem
// entweder so:
            for (int i = 0; i < tempItemnamen.Count; i++)
            {
                for (int j = 0; j < tempPfade.Count; j++)
                {
                    if (tempItemnamen[j] == tempItemnamen[i])
                    {
                        item = lvGesuchteDaten.Items.Add(tempItemnamen[i]);
                        item.SubItems.Add(tempPfade[i]);
                    }

                }
            }

// oder so, wobei ich hier wiederum die "List" mit den "Listnamen" vergleichen muesste, da die oberen eintraege fehlen.
// Dictionary ist praktisch fuer die ID
  public static void AddDoubleItems(List<string> List, ref List<string> Listnamen)
        {
            Dictionary<stringstring> KeyList = new Dictionary<stringstring>();
            for(int i =0; i< List.Count; i++)
            {
                if (KeyList.ContainsKey(List[i]) == false)
                {
                    KeyList.Add(List[i], string.Empty);
                }
                else
                {
                        Listnamen.Add(List[i]);          
                }
            }
        }


Ein weiteres Beispiel wäre:

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:
// Aus einem Forum im Netz
    public class X
    {
        private static Hashtable lookupTable = new Hashtable();
        private class Entry
        {
            public int value;

            public Entry(int value){
                this.value = value;
            }
        }

        public static string DoIt(string s)
        {
            Entry val;
            if ((val = (Entry)lookupTable[s]) == null)
            {
                val = new Entry(0);
                lookupTable[s] = val;
            }
            val.value++;

            return s;
        }
    }


//und wieder die Funktion:
            for (int i = 0; i < tempItemnamen.Count; i++)
            {
                string str= X.DoIt(tempItemnamen[i]);
                lvGesuchteDaten.Items.Add(str);
            }


und immer bleiben "einzelne" Dateien übrig, wie kann das sein?
Bin für jeden Verbesserungsvorschlag dankbar.
(Laesst sich der Code innerhalb von Html nicht besser formatieren?)


Um nochmal meine Bitte richtig zu formulieren:
Wie erhalte ich eine Liste mit doppelten Strings, die mehr als einmal vorhanden sind?
Dabei spielt es weniger eine Rolle, ob ich nur den String vergleiche oder eine md5 Checksumme.
Der Sinn wäre der selbe.


Zuletzt bearbeitet von Chiyoko am Fr 02.03.12 13:05, insgesamt 1-mal bearbeitet
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 01.03.12 18:24 
Hallo!

Ich weiß wirklich nicht, was du mit einem eigenen Hash-Algorithmus vorhast :shock:, deshalb habe ich mich mal auf die zweite Implementierung konzentriert. Aus deinem Post konnte ich nicht herauslesen, was nun bei welcher Ein- und Ausgabe schiefgeht, aber das sieht grundsätzlich ganz gut aus. Kürzer und hübscher geht es mit Linq aber natürlich immer ;) .

_________________
>λ=
Chiyoko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# / C (VS 2019)
BeitragVerfasst: Do 01.03.12 21:33 
EDIT:

Ich habe es hinbekommen.Antworten werde ich allerdings erst morgen.
Meine Augen wollen nicht mehr.
Chiyoko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# / C (VS 2019)
BeitragVerfasst: Fr 02.03.12 10:59 
Weiß der Himmel, wieso es anfangs nicht funktionierte.

Dieser Codeabschnitt liegt in einem Backgroundworker.DoWork übernimmt die Berechnung der Checksummen.
Wenn der Prozess abgeschlossen ist, werden alle Checksummen in eine Keyliste geladen.
Dabei spielen 2 Listen eine zentrale Rolle.Eine Liste beinhaltet alle Checksummen und die andere Liste
nur die Checksummen, welche mehr als einmal in der KeyListe auftreten.

In der 2ten Schleife füge ich dann nur noch die fehlenden Checksummen, die ja in der Keyliste ausgeschlossen
wurden, wieder in die Liste ein.
Die ganzen Listen machen mich noch ganz konfus.Gibt es da vielleicht eine bessere Variante?

Ich hoffe, man kann das einigermaßen nachvollziehen hehe.Danke für die Muehe.

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:
            for (int i = 0; i < Global.Tempchecksummen.Count; i++)
            {
                if (Global.ChecksummenKeyList.ContainsKey(Global.Tempchecksummen[i]) == false)
                {
                    Global.ChecksummenKeyList.Add(Global.Tempchecksummen[i], string.Empty);
                    Global.Checksummen.Add(Global.Tempchecksummen[i]);
                }
                else
                {
                    Global.TempchecksummenCopy.Add(Global.Tempchecksummen[i]);
                    Global.TempPfadeCopy.Add(Global.TempPfade[i]);
                }
            }

            for (int i = 0; i < Global.Checksummen.Count; i++)
            {
                if (Global.TempchecksummenCopy.Contains(Global.Checksummen[i]))
                {
                    Global.TempchecksummenCopy.Add(Global.Checksummen[i]);
                    Global.TempPfadeCopy.Add(Global.TempPfade[i]);
                }
            }

            this.Cursor = Cursors.WaitCursor;

            lvGesuchteDaten.BeginUpdate();
            for (int i = 0; i < Global.TempchecksummenCopy.Count; i++)
            {
                item = item.SubItems.Add(Global.TempPfadeCopy[i]);
                item.SubItems.Add(Global.TempchecksummenCopy[i]);
            }
            lvGesuchteDaten.EndUpdate();

            this.Cursor = Cursors.Default;


Oh ja, noch etwas:
Wieso bekomme ich 2 gleiche Checksummen bei unterschiedlichen Dateien und wieso ist die CRC Checksumme so klein?
Ich werde mich wohl weiter umsehen muessen.Oder reicht eine Hashtable?
Hashtables sind neuland fuer mich hehe.Mal schauen.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 02.03.12 11:43 
Zitat:
Wieso bekomme ich 2 gleiche Checksummen bei unterschiedlichen Dateien


Weil eine Checksumme oder Hash einen grossen Wertebereich auf einen kleinen Wertebereich abbildet. Prinzipbedingt kann es da keine eindeutige Abbildung geben und Kollisionen sind normal.
Deshalb kann man damit auch nur feststellen ob Dinge unterschiedlich sind (weil sie unterschiedliche Hashes haben was ein eindeutiges Kriterium ist) aber auf keinen Fall ob Dinge gleich sind. Sobald du gleiche Hashes(und erst recht Checksummen) findest müßtest du eigentlich anschließend einen binär Vergleich vornehmen um tatsächlich Gleichheit mit 100% Sicherheit festzustellen. Wenn Kollisionen bei unterschiedlichen Dateien bei dir häufig auftreten solltest du dich fragen ob denn das passende Checksummen bzw. Hashing Verfahren gewählt (und auch korrekt angewendet) wurde.

[quote]Die ganzen Listen machen mich noch ganz konfus.[quote]

Das gilt für mich bei der Betrachtung deines Code auch. Was sollen die ganzen Listen und Schleifen?
Der erste Schritt wäre mal die Logik von der UI zu trennen (lv irgendwas soll wohl ein Listview sein?) sonst fängt man nur an Code zu produzieren der zufällig zum Verhalten der ausgewählten UI Komponenten passst und vergißt nur das eigentlich Problem zu betrachten. Und eine Klasse (Instanz?) die Global heißt legt meine Stirn schon in Falten ohne das mein Hirn beteiligt ist.

Ich würde wahrscheinlich eine Klasse schreiben die jeweils eins deiner Files kapselt dort GetHashcode(für den Hash vergleich) und Equals(für den vollständigen Vergleich) überschreiben und diese dann einfach in ein HashSet werfen. Die wird dann schon melden wenn ich ein bekanntes File nochmal reinwerfe.
Chiyoko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# / C (VS 2019)
BeitragVerfasst: Fr 02.03.12 13:04 
Oh ja, schon bemerkt.Ich habe mich etwas eingelesen.Es werden Hex Zahlen generiert.

Meinen Code raeume ich immer wieder auf.Ich programmiere zwar schon viel objektorientiert, straeube mich aber auch ab und zu dagegen hehe.
Alles eine Frage der Gewohnheit.

Die Klasse Global ist eine statische Klasse.Aus dieser rufe ich saemtliche Listen und Berechnungen auf.
Aber ich sollte das etwas besser ordnen, das wird mir selbst zu unuebersichtlich.

In Bytes umwandeln ver 3facht ja gleich die Berechnung...ich raeum erstmal etwas auf;)Danke.
Logik und UI laesst sich nicht immer so einfach trennen.(z.b. im genannten Beispiel, um auf die Steuerelemente zugreifen zu können, ohne
unbedingt Klassen abzuuleiten oder Controls zu uebergeben).
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 02.03.12 13:15 
Zitat:
Es werden Hex Zahlen generiert.


Nein er wird ein Wert generiert. Ob dir das als Hex präsentiert wird ist reine Ansichtssache.

Zitat:
In Bytes umwandeln ver 3facht ja gleich die Berechnung...ich raeum erstmal etwas auf;)Danke.


Alles ist letztlich Byte da wird nix umgewandelt schon gar nicht n*mal. Was du brauchst ist einmal a.) die Hashberechnung für einen Schnellvergleich und b.) einen vollständigen Vergleich zweier Dateien der ~zufällige~ Kollisionen ausschließt. Punkt.
Chiyoko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# / C (VS 2019)
BeitragVerfasst: Di 06.03.12 13:25 
Ich habe jetzt aus meinen ganzen Listen ein multidimensionales Array mit 5 Dimensionen erstellt und initialisiert.

Damit bekomme ich zwar alle doppelten, aber nicht den ersten Eintrag.
Sozusagen fehlt jetzt immer mindestens ein Eintrag.(z.b. an index 0 und Index 6 stehen 2 gleiche.Wird jetzt der erste Eintrag
in das Dictionary geladen, fehlt dieser eintrag...)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
// Beide Arrays wurden mit der selben Groeße und den selben Dim. erstellt und initiallisiert.
// Global ist eine normale Klasse, der die Deklarationen enthaelt
// Das Array wird vorher mit Daten aus einer Listview gefuellt

int Count =0;
for (int i = 0; i < Global.Multiarray.GetLength(0); i++)
{
    if (Global.ChecksummenKeyList.ContainsKey(Global.Multiarray[i, 4]) == false)
    {
        Global.ChecksummenKeyList.Add(Global.Multiarray[i, 4], string.Empty);
    }
    else
    {
        Global.MultiarrayCopy[Count, 0] = Global.Multiarray[i, 0];
        Global.MultiarrayCopy[Count, 1] = Global.Multiarray[i, 1];
        Global.MultiarrayCopy[Count, 2] = Global.Multiarray[i, 2];
        Global.MultiarrayCopy[Count, 3] = Global.Multiarray[i, 3];
        Global.MultiarrayCopy[Count, 4] = Global.Multiarray[i, 4];
        Count++;
    }
}
Chiyoko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# / C (VS 2019)
BeitragVerfasst: Mi 07.03.12 21:17 
Problem gelöst.
Der Code ist auch kein großes Geheimnis, nur etwas umstaendlich zu posten.
Bei interesse einfach bescheid sagen.