• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

In einer binaeren Datei Positionen bestimmter Integer suchen?

Walli

Blutapfel
Registriert
06.01.06
Beiträge
2.605
Hallo,

Ich moechte in einer Binaerdatei, die einfach ein Array von 32-Bit Integern beinhaltet, nach Integern suchen, die kleiner als 0 sind und dazu die Positionen dieser Integer innerhalb der Datei wissen. Hat jemand eine Idee wie ich so etwas in einer Shell realisieren kann oder muss ich mir dafuer extra ein Programm basteln? Ich frage dies, weil ich oefters in binaeren Dateien suchen muss und da ganz unterschiedliche Sachen mache. Jedesmal ein extra Programm dafuer zu stricken, kompilieren usw. ist mir da auf Dauer zu nervig ;) .

Danke fuer Tips,
Walli
 
Zuletzt bearbeitet:

Trapper

Meraner
Registriert
12.05.05
Beiträge
231
@quarx: Ohne an den Fähigkeiten von grep zweifeln zu wollen, aber den Aufruf würde ich gerne sehen!
 

quarx

Brauner Matapfel
Registriert
17.04.05
Beiträge
8.444
Nun denn. Habe mir zunächst mal eine Binärdatei aus den 5 Integern 2,1,0,-1 und -2 als Testkandidaten erzeugt. Die Datei ist 5*4=20 Bytes groß, die Integers sind im Big-Endian Format (d.h. hohe Bytes zuerst) abgelegt. Bei Intel-Macs wäre es wahrscheinlich genau andersrum. Im Hexeditor sieht die Datei also so aus:
Code:
00 00 00 02 00 00 00 01 00 00 00 00 FF FF FF FF FF FF FF FE
Durch die Zweierkomplementdarstellung ist bei negativen Zahlen immer das höchste Bit belegt. Entspricht also einem der Fälle {8,9,A,B,C,D,E,F} für das höchste Nibble. Beim grepen müssen wir demnach jedes 8te Zeichen - beginnend mit dem ersten - auf den entsprechenden regulären Ausdruck testen.

Jetzt der Trick: "hexdump" (oder auch "od") vorschalten zur Hexadezimal-Ausgabe der Binärdatei, versehen mit einer geeigneten Formatierung. Dann ist das Suchen ein Klacks:
Code:
 hexdump -e'1/4 "%07_ax %08X\n"' binary.dat | grep ' [8-9A-F]'
Hier wird die Binärdatei z.B. mit 7spaltiger hexadezimaler Adressangabe ausgegeben, pro Zeile 4 Bytes (d.h. 8 Nibbles). Suchen muss man dann nur noch nach Leerzeichen plus eins der Anfangsnibbles. Ausgabe von hexdump alleine:
Code:
0000000 00000002
0000004 00000001
0000008 00000000
000000c FFFFFFFF
0000010 FFFFFFFE
und mit grep natürlich
Code:
000000c FFFFFFFF
0000010 FFFFFFFE

OK, die Hauptarbeit ist das Aufbereiten der Binärdaten mit dem Hexdump. :innocent:
 
  • Like
Reaktionen: Trapper

Walli

Blutapfel
Registriert
06.01.06
Beiträge
2.605
Danke für die ausführliche Antwort. Auf die Lösung wäre ich jetzt nicht so schnell gekommen. Ich könnte mir zwar vorstellen, dass es durch den Umweg über den Hexdump bei großen Dateien etwas langsam sein könnte, aber ich probiere es später mal aus. :)
 
Zuletzt bearbeitet:

pi26

Adams Parmäne
Registriert
17.12.04
Beiträge
1.297
Hallo,

eine Variante mittels Postscript (Programm als nur Text sichern und den Dateianhang ".ps" verwenden; dann mit dem Programm Vorschau öffnen).


Code:
/pfad (Users/DeinKurzname/Documents/BinaryfileTest.txt) def

a4
/x 30 def /y 800 def
/str4 4 string def
/Helvetica findfont 12 scalefont setfont

x y moveto (Datei: ) show pfad show /y y 24 sub def
x y moveto (An folgenden Indexes negative 32-Bitwerte gefunden:) show
/y y 24 sub def

/ausgabeindex 
{
y 30 lt {gsave showpage grestore /y 800 def} if
i 10 string cvs x y moveto show 
/y y 16 sub def
}def


/f pfad (r) file def
/i 0 def
{
f str4 readstring {0 get 128 ge {ausgabeindex}if}{exit}ifelse
/i i 1 add def
}
loop
f closefile

showpage

mfg pi26
 

quarx

Brauner Matapfel
Registriert
17.04.05
Beiträge
8.444
Das ist jetzt aber wirklich abgefahren, pi26! :cool:

@Walli: Mit reinem Perl funktioniert es wahrscheinlich ohne Umweg über "hexdump". Das geht mir allerdings nicht so flüssig von der Hand... :eek:
 

Walli

Blutapfel
Registriert
06.01.06
Beiträge
2.605
@Walli: Mit reinem Perl funktioniert es wahrscheinlich ohne Umweg über "hexdump". Das geht mir allerdings nicht so flüssig von der Hand... :eek:
Ja, hatte ich auch mal drüber nachgedacht. Das Problem mit Perl ist bei mir immer, dass ich meine eigenen Quelltexte nach 5 Minuten nicht mehr verstehe. Bin da auch nicht wirklich fit drin ;) .

Die Postscript-Lösung ist echt mal freakig ;) . Danke!
 
Zuletzt bearbeitet:

Walli

Blutapfel
Registriert
06.01.06
Beiträge
2.605
Ich habe mich auch noch mal an Perl versucht. Hat jemand eventuell 'ne Idee, warum folgende Loesung nicht funktioniert?

Code:
#!/usr/bin/perl

$file = $ARGV[0];
$size = -s $file;

open(FILE,"<$file") or die "Input file: Cannot open file\n\n";

$i = 0;
my $buffer;

while($i < $size) {
	read (FILE, $buffer, 4);
	use integer;
	if($buffer < 0) {
		print $i.' '.$buffer."\n";
	}
	$i = $i+4;
}

close(FILE);
 

quarx

Brauner Matapfel
Registriert
17.04.05
Beiträge
8.444
Naja, $buffer ist ja ein String, die Abfrage "$buffer<0" ist niemals wahr. Man muss die 4 Bytes "binär" in einen Integer umwandeln, z.B. mit
Code:
unpack("i",$buffer)
(wie ich mir grad ergooglete). Dann klappt's wohl.
 
  • Like
Reaktionen: Walli

Walli

Blutapfel
Registriert
06.01.06
Beiträge
2.605
Ah, das probiere ich aus. Wie gesagt... Perl ist nicht ganz mein Fall ;) . Danke!