Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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??

Geschrieben

"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).

Geschrieben

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

Geschrieben
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"?)

Geschrieben

@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...

Geschrieben

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.

Geschrieben

@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.

Geschrieben

>>??? 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 :D

Geschrieben

"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.

Geschrieben

@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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...