AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Datei auf Indikatoren für Binärdatei testen?
Thema durchsuchen
Ansicht
Themen-Optionen

Datei auf Indikatoren für Binärdatei testen?

Ein Thema von PeterPanino · begonnen am 9. Mai 2015 · letzter Beitrag vom 13. Mai 2015
Antwort Antwort
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 08:05
Und ein Null-Byte ist kein Indikator. In UTF-16 Codiert gespeicherten Dateien wirst du sehr viele 0er Byte finden. So wäre das $-Zeichen als 00 24 in der Datei vorhanden.

Für mich wäre zwei Null-Bytes hintereinander ein Indikator.
Oder das Prüfen auf die Bekannten Magic Bytes. In Wikipedia (http://en.wikipedia.org/wiki/List_of_file_signatures) gibts hierfür eine kleine Liste
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#2

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 09:39
Im Prinzip wären das 2 Ansätze:
  1. Interpretieren als die Text: Abbrechen bei Fehlern in der Codierung, Testen auf verbotene Zeichen
  2. Testen auf bekannte Magic-Bytes

1. Der Scan-Ansatz kann leicht in Arbeit ausarten, wenn man viele Kodierungen unterstützen will. Außerdem muss man sich genau überlegen, welche Zeichen man verbieten möchte und welche vielleicht doch im Text vorkommen können. Wenn man nur auf Nullbytes testen möchte, kann man sich den größten Teil der Arbeit bei der Dekodierung vermutlich sparen.

2. Das Testen auf die Magic-Bytes ist auf jeden Fall interessant, da es quasi nichts kostet. Man sollte aber beachten, das einige Magic-Bytes valider Text sind und auch am Anfang von Textdokumenten vorkommen könnten.
  Mit Zitat antworten Zitat
PeterPanino

Registriert seit: 4. Sep 2004
1.451 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 13:57
Ich habe die Funktion jetzt erweitert:

1. Testen auf Doppel-NullBytes anstatt auf einfache NullBytes

2. Testen auf mehr als n verbotene ControlBytes

Delphi-Quellcode:
function IsTextFile(const AFile: string; const ABytesCount: Integer = 1000): Boolean;
// testet, ob die ersten ABytesCount Bytes einer Datei Indikatoren für eine Binär-Datei enthalten:
// wenn nicht, muss es wohl eine Textdatei sein?
// Siehe auch: http://qc.embarcadero.com/wc/qcmain.aspx?d=84071
const
  MaxAllowedForbiddenControlCharsCount = 1;
var
  Reader: TStreamReader;
  Ch: AnsiChar;
  c: Integer;
  PreviousCharWasNullByte: Boolean;
  ForbiddenControlCharsCount: Integer;
begin
  Result := True;
  c := 0;
  PreviousCharWasNullByte := False;
  ForbiddenControlCharsCount := 0;

  Reader := TStreamReader.Create(TFileStream.Create(AFile, fmOpenRead), TEncoding.ANSI);
  try
    if Reader.EndOfStream then
    begin
      CodeSite.Send('Nothing to read');
      Result := False;
      EXIT;
    end;

    while Reader.Peek() >= 0 do
    begin
      Ch := AnsiChar(Reader.Read());

      if Ch = #0 then
      begin
        if PreviousCharWasNullByte then
        begin
          CodeSite.Send('Double Null Byte found');
          Result := False;
          EXIT;
        end;
        PreviousCharWasNullByte := True;
      end
      else
      begin
        PreviousCharWasNullByte := False;

        if Ch in [#1..#8, #14..#31] then
        begin
          Inc(ForbiddenControlCharsCount);
          CodeSite.Send('This forbidden control char', HexDisplayPrefix + IntToHex(Ord(Ch), 2));
        end;
        if ForbiddenControlCharsCount > MaxAllowedForbiddenControlCharsCount then
        begin
          CodeSite.Send('More than ' + IntToStr(MaxAllowedForbiddenControlCharsCount) + ' forbidden control chars found');
          Result := False;
          EXIT;
        end;
      end;

      // Todo: andere Indikatoren?

      Inc(c);
      if c > ABytesCount then EXIT;
    end;
  finally
    CodeSite.Send('Bytes read', c);
    Reader.Close();
    Reader.BaseStream.Free;
    Reader.Free();
  end;
end;

procedure TForm1.btnTestClick(Sender: TObject);
var
  d: Int64;
begin
  d := GetTickCount;
  CodeSite.Send('Is Text File?', IsTextFile(edt1.Text));
  CodeSite.Send('Duration', GetTickCount - d);
end;
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#4

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 14:41
Gibt es Anzeichen für BOM? Wenn ja, versuche, die nächsten paar Bytes entsprechend zu interpretieren.
Wenn nicht, kann es
a) eine Unicode-Datei ohne BOM
b) eine ASCII-Datei
c) eine Binärdatei sein

Bei (a) ist jedes zweite Byte eine 0. Vermutlich.
Bei (b) sind die Bytes=9,10,30 oder >=32 und <= 127. Meistens.

Du erstellst also eine Häufigkeitstabelle der ersten paar Zeichen (N=20 z.B.)
Bestehen die Bytes nur aus Zeichen, Ziffer, CR/LF? Dann handelt es sich vermutlich um eine Textdatei.
Haben wir fast so viele Nullen wie sonstige Bytes und sind die Bytes auch Zeichen, Ziffer CR/LF? Dann ist es vermutlich eine Unicode-Datei
Ansonsten ist die Wahrscheinlichkeit groß, das es sich um eine Binär bzw. um keine Textdatei handelt.

Aber sicher kannst Du nicht immer sein.
  Mit Zitat antworten Zitat
PeterPanino

Registriert seit: 4. Sep 2004
1.451 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 14:52
Gibt es Anzeichen für BOM? Wenn ja, versuche, die nächsten paar Bytes entsprechend zu interpretieren.
Wenn nicht, kann es
a) eine Unicode-Datei ohne BOM
b) eine ASCII-Datei
c) eine Binärdatei sein

Bei (a) ist jedes zweite Byte eine 0. Vermutlich.
Bei (b) sind die Bytes=9,10,30 oder >=32 und <= 127. Meistens.

Du erstellst also eine Häufigkeitstabelle der ersten paar Zeichen (N=20 z.B.)
Bestehen die Bytes nur aus Zeichen, Ziffer, CR/LF? Dann handelt es sich vermutlich um eine Textdatei.
Haben wir fast so viele Nullen wie sonstige Bytes und sind die Bytes auch Zeichen, Ziffer CR/LF? Dann ist es vermutlich eine Unicode-Datei
Ansonsten ist die Wahrscheinlichkeit groß, das es sich um eine Binär bzw. um keine Textdatei handelt.

Aber sicher kannst Du nicht immer sein.
Ist viel zu aufwendig und unsicher. Meine bisherigen Tests haben gezeigt, dass die Prüfung auf verbotene ControlBytes und Doppel-NullBytes sehr zuverlässig ist. Bitte zeigt mir auch nur EINE Datei, wo diese Prüfung nicht funktioniert hat.
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.005 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 15:08
Ist viel zu aufwendig und unsicher. Meine bisherigen Tests haben gezeigt, dass die Prüfung auf verbotene ControlBytes und Doppel-NullBytes sehr zuverlässig ist. Bitte zeigt mir auch nur EINE Datei, wo diese Prüfung nicht funktioniert hat.
Einige Beispiele sind unter https://de.wikipedia.org/wiki/Unicod...rmation_Format zu finden. UTF-32 enthält doppelte Null-Bytes, UTF-16 enthält auch "verbotene" ControlBytes:

Zitat:
00 6D|00 6B|00 3A|04 1F|04 40|04 3E|04 3C|04 35|04 3D|04 30 | UTF-16BE
m |k |: |П |р |о |м |е |н |а | mk:Промена

3E 04 00 00|3C 04 00 00|35 04 00 00|3D 04 00 00|30 04 00 00 | UTF-32LE
00 00 04 3E|00 00 04 3C|00 00 04 35|00 00 04 3D|00 00 04 30 | UTF-32BE
о |м |е |н |а | омена
Michael Justin

Geändert von mjustin ( 9. Mai 2015 um 15:10 Uhr)
  Mit Zitat antworten Zitat
PeterPanino

Registriert seit: 4. Sep 2004
1.451 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Datei auf Indikatoren für Binärdatei testen?

  Alt 9. Mai 2015, 15:15
Kann man davon ausgehen, dass UTF-16- und UTF-32-Dateien statistisch signifikant so gut wie immer einen BOM enthalten?
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz