MP3 Datei auslesen und neu schreiben



  • Hi,

    ich habe wieder ein Anfänger Problem: 🙂

    Ich möchte z. B. eine MP3 oder EXE Datei einlesen und den den Inhalt in eine neue Datei schreiben, so dass die MP3/EXE im Grunde eine Kopie ist.

    Dies ist nur die Basis für etwas anderes, an dem ich gerade programmiere.

    Habe dazu folgenden einfachen Code:

    string content;
    
    ifstream file("demo.mp3", ios::binary);
    file >> content;
    file.close();
    
    ofstream write("demo.txt", ios::binary);
    write << content;
    write.close();
    

    Jedoch steht in der neuen Datei "demo.txt" nur "ÿû¤d" drin und nicht alles der Original-Datei.

    Ich muss die Datei so einlesen, dass ich jedes Zeichen der Datei einzeln durchgehen kann, z. B. für eine XOR Verknüpfung (also Stichwort: Verschlüssung).

    Kann jemand helfen?

    gruß
    ac!d



  • Du wirst höchstwarscheinlich in nem String keine Binärdaten speichern können.

    Außerdem solltest du noch satt nur ios::binary zB ios::in|ios::binary bzw. ios::out|ios::binary benutzen (ich hab keine Ahnung von diesem ios::binary

    edit:probiers ma hiermit:
    http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=6043&lngWId=3
    edit:wird dir wohl auch nix bringen



  • So?

    #include <iostream>
    #include <fstream>
    using namespace std;
    int main()
    {
    char buffer[1024];
    ifstream in("toll.mp3", ios::binary);
    ofstream out("toll.txt", ios::binary);
    
    in.read(&buffer, sizeof(buffer));
    out.write(&buffer, sizeof(buffer));
    
    return 0;
    }
    

    Wenn das Progamm funzt, liest es ein 1024 Byte großen Block ein und schreibt ihn in die neue Datei. Wenn du die txt aber mit einem normalen Editor öffnest, kann es durchaus sein, dass er Müll produziert. (Liegt wohl an der Tatsache, dass Musik nicht im ASCII enthalten ist.)



  • op<</>> sind auch nicht das richtige Werkzeug, du musst schon mit read/write arbeiten.
    Und ein ios::in oder ios::out wird bei ifstream und ofstream nicht benötigt.



  • Hier mal mein (ein) ansi-c quellcode für dich.
    Hatte am Anfang auch das Problem. Lass Dir mal die Position des Dateizeigers ausgeben... Zur Lösung setzte ich den Dateizeiger vor dem Kopieren, an den Dateianfang. (Schau Dir die makexor Funktion an.)

    Was Du am Code besser machen könntes in cpp, ist die Verschlüsselung selbst in mehrere theards aufteilen damit es schneller geht.

    /* xor.c
       xor-Verknüpfung (Verschlüsselung) - ANSI C-Standart
    
       This program is free software; you can redistribute it and/or modify it
       under the terms of the GNU General Public License as published by the Free Software Foundation;
       either version 2 of the License, or (at your option) any later version.
    
       This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
       without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       See the GNU General Public License for more details.
       You should have received a copy of the GNU General Public License along with this program;
       if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     */
    
    #include <errno.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    struct option {
       long start; // Startposition in der xor-Eingabedatei
       int  loop;  // Wiederholungen der xor-Verknüpfung
    }opt;
    
    int  *ac;   // globaler Zeiger auf argc
    char **av;  // globaler Zeiger auf *argv[]
    FILE *f[3]; // Eingabedatei, xor-Eingabedatei und Ausgabedatei
    
    void showhelp       (void);
    char *getopt        (char *opt);
    FILE *getfile       (char *path, char *m);
    int  openinputfile  (void);
    int  openoutputfile (void);
    int  openxorfile    (void);
    void setstart       (void);
    void setloop        (void);
    void makexor        (void);
    
    int main (int argc, char *argv[])
    {
       int i;
       fprintf (stdout, "XOr comes with ABSOLUTELY NO WARRANTY.\nThis is free software under the terms of the GNU General Public License.");
       // Kommandozeilenparameter prüfen
       if (argc < 2){
          fprintf (stderr, "\nUseage: %s input [options]", argv[0]);
          showhelp ();
          return (EXIT_FAILURE);
       }
       ac = &argc;
       av = argv;
       // Dateien öffnen
       if ((openinputfile () == EXIT_SUCCESS)    // Eingabedatei
       &&  (openoutputfile () == EXIT_SUCCESS)){ // Ausgabedatei
          if (openxorfile () == EXIT_SUCCESS){   // xor-Eingabedatei
             // Einstellungen setzen
             setloop ();  // Wiederholungen der xor-Verknüpfung
             setstart (); // Startposition in der xor-Eingabedatei
             // xor-Verknüpfung starten
             makexor ();
          }
       }
       // offene Datenströme schließen
       for (i = 2; i > -1; i--)
          if (f[i] != NULL)
             fclose (f[i]);
       fprintf(stdout, "\nEND");
       return (EXIT_SUCCESS);
    } /* main () */
    
    /* Hilfetext */
    void showhelp(void) {
       printf("\nSorry no help included, show readme...");
    } // showhelp ()
    
    /* Einstellung suchen und deren Wert zurückgeben */
    char *getopt (char *opt){
       int i;
       char *val = NULL; // Wert (value)
       for (i = 2; i < *ac; i++){
          if (strncmp (av[i], opt, strlen(opt)) == 0){
             val = strchr(av[i], (int) '=');
             val = &val[1]; // '=' Zeichen abschneiden
          }
       }
       return (val);
    } // getopt ()
    
    /* Datei (Datenstrom) öffnen */
    FILE *getfile (char *path, char *m)
    {
       FILE *f = NULL;
       errno = 0;
       f = fopen (path, m);
       if (f == NULL)
          fprintf (stderr, "%s (\"%s\")", strerror (errno), path);
       return (f);
    } // getfile ()
    
    /* Eingabedatei öffnen */
    int openinputfile (void)
    {
       fprintf (stdout, "\nopen input-file... ");
       if ((f[0] = getfile (av[1], "rb")) == NULL)
          return (EXIT_FAILURE);
       fprintf (stdout, "Successed");
       return (EXIT_SUCCESS);
    } /* setinputfile */
    
    // Augabedatei öffnen
    int openoutputfile (void)
    {
       fprintf (stdout, "\nopen output-file... ");
       char *path;
       path = getopt ("o="); // Komandozeienparameter?
       if ((path == NULL) || (strcmp (path, av[1]) == 0))
          f[2] = getfile(av[1], "r+b");
       else
          f[2] = getfile(path, "w+b");
       if (f[2] == NULL)
          return (EXIT_FAILURE);
       fprintf (stdout, "Successed");
       return (EXIT_SUCCESS);
    }// setoutputfile ()
    
    /* xor-Eingabedatei öffnen (Datei oder Zeichenkette) */
    int openxorfile (void)
    {
       char usr, *c, *path;
       path = getopt ("x="); // Komandozeilenparameter?
       if (path == NULL){
          fprintf (stdout, "\nInput xor (file or string): ");
          while ((usr = fgetc (stdin)) != '\n'){
             c = (char *) realloc (c, sizeof(*c) + 1);
             if (c == NULL){
                fprintf(stderr, "ERRNO1");
                return (EXIT_FAILURE);
             }
             strncat(c, &usr, 1);
          }
          if (c == NULL)
             c = "";
          path = c;
          free (c);
       } else {
          fprintf (stdout, "\n");
       }
       fprintf (stdout, "open xor input-file... ");
       if ((f[1] = getfile (path, "rb")) == NULL){
          // Zeichenkette
          // Temporäre Datei anlegen und den Inhalt der Zeichenkette hineinschreiben.
          fprintf (stdout, "\ncreate and open a temporary file as xor input-file... ");
          if ((f[1] = getfile (tmpnam (NULL), "w+b")) != NULL){
             fputs (path, f[1]);
             fprintf (stdout, "Successed\n(xor is string - temporary file)");
             return (EXIT_SUCCESS);
          }
       } else {
          // Datei
          fprintf (stdout, "Successed\n(xor is file)");
          return (EXIT_SUCCESS);
       }
       return (EXIT_FAILURE);
    } // setxorfile ()
    
    /* Startposition in der xor-Eingabedatei. Wert abfragen und setzen. */
    void setstart (void)
    {
       char *c;
       //c = getopt ("s="); // Komandozeienparameter?
       opt.start = 0;//(long) atol(c);
    } // setstart()
    
    /* Wiederholungen der xor-Verknüpfung. Wert abfragen und setzen. */
    void setloop (void)
    {
       char *c;
       //c = getopt ("l="); // Komandozeienparameter?
       opt.loop = 0;//(int) atol(c);
    } // setloop()
    
    /* xor-Verknüpfen */
    void makexor(void)
    {
       time_t s, e;
       int i, c, x;
       fprintf(stdout,"\nstart...");
       for (i = 2; i > -1; i--){
          clearerr (f[i]);
          rewind (f[i]);
       }
       // Startposition in der xor-Eingabedatei setzen
       fseek (f[1], opt.start, SEEK_SET);
       s = time (NULL);
       // Eingabe lesen
       while (((c = fgetc (f[0])) != EOF) && (!feof (f[0]))){
          fprintf (stdout, "\rrunning... (%d byte)", ftell (f[0]));
          // xor einlesen
          x = fgetc (f[1]);
          if ((x == EOF) && (feof (f[1]))){
             rewind (f[1]);
             x = fgetc (f[1]);
          }
          // xor verknüpfen und ggf. wiederholen
          for (i = opt.loop; i > -1; i--)
             c ^= x;
          // Ausgabe schreiben
          fputc (c, f[2]);
       }
       e = time (NULL);
       fprintf (stdout, " Done (time: %.0f seconds)", difftime (e, s));
    } // makexor ()
    


  • tito schrieb:

    Was Du am Code besser machen könntes in cpp, ist die Verschlüsselung selbst in mehrere theards aufteilen damit es schneller geht.

    Was man natürlich auch noch besser machen könnte in C++ wäre das in C++ zu schreiben :p

    *SCNR*



  • hmm ist mir zu doof diesen sinn freien Müll noch durchzulesen ...

    Also um auf deine Frage zu antworten ... du musst halt die Differenz von dem Anfang der Datei und dem Ende nehmen ... damit hast du die Länge ... dann einen Array mit dieser Größe anlegen ... fertig!

    #include <iostream>
    #include <fstream>
    
    int main()
    {
    	std::ifstream in("toll.mp3", std::ios::in | std::ios::binary);
    	if (in.is_open() == false)
    		return 0;
    
    	in.seekg(0, std::ios::beg);
    	std::ios::pos_type pos_begin = in.tellg();
    	in.seekg(0, std::ios::end);
    	unsigned int file_length = unsigned int(in.tellg() - pos_begin);
    	in.seekg(0, std::ios::beg);
    
    	unsigned char* buffer = new unsigned char[file_length];
    	in.read((char*)(buffer), file_length * sizeof (unsigned char));
    	in.close();
    
    	std::ofstream out("toll.txt", std::ios::out | std::ios::binary | std::ios::trunc);
    	if (out.is_open() == false)
    		return 0;
    
    	out.write((char*)(buffer), file_length * sizeof (unsigned char));
    	out.close();
    
    	return 0;
    }
    


  • LordJaxom schrieb:

    Was man natürlich auch noch besser machen könnte in C++ wäre das in C++ zu schreiben :p

    *SCNR*

    man könnte es auch bleiben lassen und die ppd wählen!



  • Erstmal danke. Der Code von (D)Evil läuft einwandfrei.

    Jedoch wie kann ich nun den Inhalt der Datei Zeichen für Zeichen XOR verknüpfen?
    Ich hatte es mir so vorgstellt:

    Pseudo-Code:

    def content = binaryContent("demo.mp3");
    def encrypt[content.length()];
    def n = 0;
    
    while (n < content.length())
    {
        encrypt[n] = content[n]^5;
        n++;
    }
    

    Wie kann ich das in C++ realisieren?
    Mit dem Beispiel kann ich irgendwie nicht XOR verknüpfen (bekomme es zumindest nicht hin)?

    Soll eine sehr einfache Verschlüssung sein ...

    Gruß
    ac!id



  • *PUSH*



  • ac!d schrieb:

    Mit dem Beispiel kann ich irgendwie nicht XOR verknüpfen (bekomme es zumindest nicht hin)?

    Eigentlich sollte das ja auch dein Programm machen, oder? 😉

    Also wo genau klappt's noch nicht?

    mfg.



  • Habs jetzt hinbekommen. Danke an alle! 🙂


Anmelden zum Antworten