Checksumme



  • Hi,

    ich bräuchte eine Möglichkeit für eine beliebige Datei eine Checksumme, Prüfsumme, Signatur oder wie man es auch nennen will berechnen.

    Ich habe bereits Implementierungen für einige Hash-Verfahren (SHA-128, SHA-256, SHA-512, etc.).

    Das ist also nicht das Problem. Mich quält viel mehr die Frage, wie ich mit diesen Verfahren nun die Checksumme berechne. Ich kann ja schlecht 1 GB in den Speicher laden und darauf dann die SHA-Funktion anwenden. Wie wird sowas also gemacht? Lädt man die Datei in Blöcken in den Speicher und wendet auf jeden Block erneut die Hash-Funktion an? Aber was macht man mit dem vorherigen Hash-Wert? Der muss ja wieder mit einbezogen werden...

    Da bin ich mir bei der Implementierung etwas unsicher. Wie soll ich es lösen?

    Viele Grüße
    Timo Hermann



  • Normalerweise erstellst du erst einen Kontext und kannst dann der jeweiligen Funktion blockweise Daten übergeben. Wie das der Algorithmus intern macht, kann ich dir jetzt nicht sagen, aber er kümmert sich selbst darum, dass alle Daten einbezogen werden, die du zuführst. 😉

    Unabhängig von der Implementierung (Pseudo-Code):

    #define BUFFER_GROESSE 4096 /* oder so */
    
    char buffer [BUFFER_GROESSE];
    
    algo_context_erstellen ();
    
    while (!eof ())
    {
        daten_lesen (&buffer, BUFFER_GROESSE);
        algo_daten_hinzufuegen (&buffer, BUFFER_GROESSE);
    }
    
    algo_hash_geben_lassen ();
    
    algo_context_freigeben ();
    


  • naja, du hast ja sicher ne schleife die ueber die daten geht, sowas in der art

    ...V=0;
    for(int a=0;a<SIZE;a++)
    {
      Wert = pEingangsdaten[a];
      V = Hashfunction(V,Wert);
    }
    

    statt nun pEingangsdaten direkt zu benutzen, rufst du eine funktion auf

    ...V=0;
    for(int a=0;a<SIZE;a++)
    {
      Wert = Eingangsdaten(a);
      V = Hashfunction(V,Wert);
    }
    

    die im einfachsten fall

    ...Eingangsdaten(int Index)
    {
      return pEingangsdaten[Index];
    }
    

    jetzt kannst du in der Eingangsdaten funktion immer die gewuenschte datei oeffnen, z.b. 1MB in einen buffer einlesen und dann solange die daten zurueckliefern, bis du wieder 1MB nachlesen musst
    z.b.

    int Offset=~0;
    ...Eingangsdaten(int Index)
    {
      //falls das momentane im array nicht den selben offset hat in 1MB stuecken
      //wie das was gefordert wird
      if((Index>>20)!=Offset)
      {
        //neuer Offset
        Offset = (Index>>20);
        //oeffne datei
        FILE File=open...
        //setze den lese index auf die 1MB basis von "Index"
        SetFileOffset(Offset<<20);
        //Lese 1MB
        Read(pEingangsdaten,1MB);
        close(File);
      }
    
      //gib wert zurueck, minus den offset.
      return pEingangsdaten[Index-(Offset<<20)];
    }
    

    bedenke
    -es kann sein dass eine datei mehr als 32bit, 2GB, ist. int reicht dann nicht.
    -es kann sehr langsam sein 1GB zu lesen, bei einer guten platte mit z.b. 40MB/s und zugriffszeiten locker ne minute nur lesen, ein gut optimierter MD5 kommt auf vielleicht 100MB/s, bist also minuten fuer groessere datein am rechnen, bau also ne progress anzeige ein, sonst weiss man nie, ob es sinnvolles macht 😉

    ich hoffe das beispiel ist verstaendlich (und dass ich deine frage verstanden hatte 😉 )



  • Timo Hermann schrieb:

    Wie soll ich es lösen?

    zu dem bereits gesagten: wenn du windoofs benutzt, dann schau dir mal das an:
    http://msdn.microsoft.com/en-us/library/aa366556(VS.85).aspx
    damit kannste einiges an speed gewinnen.
    🙂



  • Vielen Dank, ich konnte es nun lösen.

    Es wird sogar eine entsprechende Funktion angeboten, die im Beispielquellcode aber in einer anderen Funktion gekapselt war und mir deshalb entgangen ist.


Anmelden zum Antworten