Phatmaxx Geschrieben 13. April 2003 Geschrieben 13. April 2003 Hallo Leute, ich hab schon die ganze zeit gesucht aber ich bin nicht wirklich fündig geworden. Ich möchte eine Datei (binär) nach Hex und wieder von Hex zurück nach Binär konvertieren. Das ganze möchte ich mit C/C++ machen, hab jedoch nicht wirklich eine Idee, wie genau ich das machen soll. Ich dachte mir, evtl. muss man die Datei zeichenweise einlesen und dann jeden Ascii-Character nach Hex konvertieren aber das dauert bei grösseren Dateien ja eine halbe Ewigkeit.. Hat jemand eine Idee/Vorschlag?? Zitieren
Crush Geschrieben 13. April 2003 Geschrieben 13. April 2003 "Ich dachte mir, evtl. muss man die Datei zeichenweise einlesen ..." ->Genauso würde ich das auch tun. ".. und dann jeden Ascii-Character nach Hex konvertieren aber das dauert bei grösseren Dateien ja eine halbe Ewigkeit.." Die Frage ist natürlich, was Du unter einer halben Ewigkeit verstehst und wie lang die Datei denn sein soll? Viel Konvertieren muß man nicht unbedingt. Man kann genausogut eine Tabelle mit 256 Hex-Werten nehmen und je nach Zeichen den 2stelligen Hexwert auslesen (und andersrum genauso). Natürlich könnte man auch "hart" alles umrechnen oder mit dem format-Befehl die Zahlen konvertieren lassen, aber das wär halt nicht ganz sooooo schnell (aber immer noch schnell genug, daß man davon nicht besonders viel mitbekommt). Zitieren
nic_power Geschrieben 13. April 2003 Geschrieben 13. April 2003 Hallo, naja, eine halbe Ewigkeit dauert das sicherlich nicht (auch nicht bei groesseren Dateien). Diese Methode wird uebrigens schon seit Jahrzehnten im Usenet (in leicht abgewandelter Form) verwendet. uuencode/uudecode "formatiert" Binaerdateien so um, dass sie ueber ein 7 Bit Mail/News System transportiert werden koennen - aehnliches macht auch "BinHex". Quellcode fuer beide Tools sollte leicht per google zu finden sein. Fuer eine Konvertierung nach Hex und zurueck sollte sich ohne Probleme als 10 Zeiler implementieren lassen (eine Richtung per printf() die andere mit "atoi()"). Nic Zitieren
Phatmaxx Geschrieben 14. April 2003 Autor Geschrieben 14. April 2003 Original geschrieben von nic_power Hallo, naja, eine halbe Ewigkeit dauert das sicherlich nicht (auch nicht bei groesseren Dateien). Diese Methode wird uebrigens schon seit Jahrzehnten im Usenet (in leicht abgewandelter Form) verwendet. uuencode/uudecode "formatiert" Binaerdateien so um, dass sie ueber ein 7 Bit Mail/News System transportiert werden koennen - aehnliches macht auch "BinHex". Quellcode fuer beide Tools sollte leicht per google zu finden sein. Fuer eine Konvertierung nach Hex und zurueck sollte sich ohne Probleme als 10 Zeiler implementieren lassen (eine Richtung per printf() die andere mit "atoi()"). Nic :uli Danke für die schnelle Antwort, also war die Idee mit dem zeichenweisen konvertieren doch ned so schlecht... Ich werde mal eine runde danach googlen (oder goog"eln"?) Zitieren
Phatmaxx Geschrieben 14. April 2003 Autor Geschrieben 14. April 2003 @Crush: Sorry, hab Deinen Post irgendwie voll übersehen! Die Dateien sind unterschiedlich gross, ich bastel grade an einem kleinen Verschlüsselungsprogramm und da der binäre Output ziemlich krank aussieht und auch ned so gut per E-Mail zu verschicken ist nun diese Idee mit dem verHexen... Zitieren
A-RAM Geschrieben 16. April 2003 Geschrieben 16. April 2003 hmmm ich hab eben einen ellenlangen Text getippt, und der ist mir verlorengegangen weil diese Schei*registrierung hier x-tausend Stufen mit zig Kennwörtern hat!! ich machs diesmal kurz: Lies deine Datei in Puffer bevor du überhaupt was damit machst!! Puffergrößen: 512 Byte bei kleinen Dateien, 4096 bei großen. Arbeite einen Puffer nach dem anderen ab. PS. es gibt Formeln im Netz, die die optimale Puffergröße berechnen. Wenn du n HexEditor schreibst, dann lies nicht die komplette Datei ein wenn die arg groß ist, sonden nur das was man gerade sieht, und das wo man demnächst hinscrollen könnte. Vergiss bitte _sofort_ den Vorschlag mit der Tabelle!!! Es ist ein Frevel jedes Zeichen im Durchschnitt gegen 128 andere zu prüfen!! Jedes Zeichen das du liest verbrät eh schon mindestens zwei Speicherzugriffe (lesen + schreiben) da brauchen wir keine weiteren 128!! Zudem sind Stringvergleiche sündhaft teuer! Nimm einen mathematischen Algorithmus, der dir deinen Binären (Integerwert) des Zeichens von dezimalen System ins hexadezimale System umrechnet. Ein guter Algo braucht dazu nur wenige Anweisungen und das ganze ist in wenigen Zeilen implementiert. Wenn du ein wenig Assembler lernen möchtest, kannst du sogar deinen Code so optimieren, das er kaum Speicherzugriffe macht, und die Werte weitgehend in den Registern hält. Zitieren
Crush Geschrieben 16. April 2003 Geschrieben 16. April 2003 @A-RAM: ??? Warum soll das mit der Tabelle 128 Vergleiche nach sich ziehen ??? Wie kommst Du überhaupt auf 128??? Eine schnellere Methode als den Tabellentrick gibt es doch gar nicht. Der ASCII-Wert ist dabei nämlich der Tabellenindex und die Hexwerte werden dann aus der Tabelle gelesen. Gerade wenn Du von Assembler sprichst: Dort gibt es dafür sogar den speziellen Table-Lookup-Befehl XLAT, welcher beim PPro nur 2 Taktzyklen benötigt und beim Athlon trotzdem sauschnell ist, obwohl er über VectorPath dekodiert wird und somit die DirektPath-Instruction-Pipeline unterbricht. Zeig mir erst mal den Algorithmus, der schneller ist als XLAT - hier können nämlich auch alle Werte (bis auf die Tabelleninhalte) in den Registern gehalten werden, doch bei mehrfachem Zugriff landen die ohnehin im Data-Cache und spätestens beim 2. Zugriff auf einen Eintrag flutscht es nur so. Zitieren
A-RAM Geschrieben 16. April 2003 Geschrieben 16. April 2003 >>??? Warum soll das mit der Tabelle 128 Vergleiche nach sich ziehen ??? Wie >>kommst Du überhaupt auf 128??? Durchschnittlich 128, da ich von 256 Zeichen ausgehe. >>Eine schnellere Methode als den Tabellentrick gibt es doch gar nicht. Der ASCII- >>Wert ist dabei nämlich der Tabellenindex und die Hexwerte werden dann aus der >>Tabelle gelesen. Na das du das im Hinterkopf führst, solltest du aber dazuschreiben *g für mich sah das aus wie: for(int i = 0; i<strlen;++i){ for(int j = 0; j < tablelen; ++j) if(str == table[j] return table; >>Gerade wenn Du von Assembler sprichst: Dort gibt es dafür sogar den speziellen >>Table-Lookup-Befehl XLAT, welcher beim PPro nur 2 Taktzyklen benötigt und beim >>Athlon trotzdem sauschnell ist, obwohl er über VectorPath dekodiert wird und >>somit die DirektPath-Instruction-Pipeline unterbricht. Meines Wissens nach verbraucht XLAT 11 Takte. Bin aber warscheinlich auf älterem Stand >>Zeig mir erst mal den Algorithmus, der schneller ist als XLAT - hier können nämlich >>auch alle Werte (bis auf die Tabelleninhalte) in den Registern gehalten werden, >>doch bei mehrfachem Zugriff landen die ohnehin im Data-Cache und spätestens >>beim 2. Zugriff auf einen Eintrag flutscht es nur so. Es geht mir drum, das du jedes Zeichen durchschnittlich gegen 128 andere prüfst. Sprich du lädst das Zeichen, dann das aus der Tabelle vergleichst die beiden (auch Cache ist teuer), und hältst dann noch jedesmal einen Sprung bereit, der fast immer auch noch ausgeführt wird. Sprünge sind auch nicht gerade billig. Zudem lassen sich Sprünge (wenn wir parallelisieren wollen) nur mit wenigen Instruktionen vereinen. In einer Umrechnung arbeitest du mit billigen moves und shifts. Und die loopt noch lange nicht soviel wie eine Prüfung. Vielleicht schrieb ich mal n kleinen test. lass mich natürlich auch gern überzeugen Zitieren
A-RAM Geschrieben 16. April 2003 Geschrieben 16. April 2003 ps. man vergebe mir die Klammer, die ich zuviel, bzw. zuwenig gesetzt hab *ggg Zitieren
Crush Geschrieben 17. April 2003 Geschrieben 17. April 2003 "Meines Wissens nach verbraucht XLAT 11 Takte. Bin aber warscheinlich auf älterem Stand" Ich habe die Taktangabe aus Franzis´ prof. Assembler Referenz, welche auch schon steinalt ist. Der Staubschicht nach, bestimmt auf dem Stand von 98. Wenn die Befehlsoptimierer und Hardwareverdrahter bei AMD gut gearbeitet haben, sollte auch dieser Mnemonic - wie gewohnt - etwas schneller geworden sein. Zitieren
nic_power Geschrieben 17. April 2003 Geschrieben 17. April 2003 @A-RAM: for(int i = 0; i<strlen;++i){ for(int j = 0; j < tablelen; ++j) if(str[i] == table[j] return table[i]; was moechtest Du denn mit diesem Code-Fragment erreichen? In dem Thread geht es um die Konvertierung von Bin nach Hex, dafür ist der von dir vorgeschlagene Algorithmus ungeeignet. Abgesehen davon ist der Code ausgesprochen ineffizient, da Du auch direkt indizieren kannst und die damit die zweite Schleife komplett sparst: return table(str[i]); strlen zu verwenden ist ebenfalls keine gute Idee, da dabei Probleme mit dem Wert "0" auftreten (diese markiert das Stringende, aber nicht das Ende einer Datei oder eines Puffers, der Binärcode enthält!). Aber wie gesagt, das war nicht die Frage. In der ging es um die Abbildung von Bin nach Hex und vice versa: for (i=0; i<BUFFERSIZE; i++) printf("%02x ", buffer[i]); Nic Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.