Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen? (https://www.delphipraxis.net/192160-mac-hersteller-zuordnung-bzw-wie-mit-einem-sehr-grossen-datensatz-umgehen.html)

p80286 24. Mär 2017 08:00

AW: MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen?
 
Zitat:

Zitat von haentschman (Beitrag 1365440)
Moin...:P

Wenn es keine DB hat,

Die braucht man nicht, die Denke ist wichtig.
Wäre interessant, was schneller wäre Tdictionary oder der "DB-Ansatz"

Gruß
K

haentschman 24. Mär 2017 09:05

AW: MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen?
 
Zitat:

War auch meine erste Idee. Nur er will alles in einer Datei weiter geben ohne (Installation.
:gruebel: bezog sich das auf meinen Beitrag oder die DB Lösung? :zwinker:
Zitat:

Zu 1.: Als Textdatei als Ressource einkompilieren und zur Abfrage temporär entpacken.
...das hatte ich übersehen. :oops:
Zitat:

Wäre interessant, was schneller wäre Tdictionary oder der "DB-Ansatz"
...deutlich TDictionary. :zwinker:

CodeX 24. Mär 2017 09:50

AW: MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen?
 
Zitat:

Zitat von p80286 (Beitrag 1365430)
Das ist doch eine typische Datenbankanwendung.
Die Daten normalisieren, sprich zwei Tabellen erstellen und dann mit binärer Suche dadurch hüpfen.

Genauso hätte ich das bei einer Webseite gemacht. Aber da ich in meinem Delphi-Projekt sonst nicht mit Datenbanken arbeite, wollte ich dieses Fass nur dafür nicht aufmachen.

Zitat:

Zitat von haentschman (Beitrag 1365440)
Für die Lagerung der Informationen käme ein TDictionary<string, string> in Frage.

Ich würde ja wahnsinnig gerne mit Generics arbeiten. Aber nachdem ich damals festgestellt habe, dass jede einzelne Verwendung von Generics die Exe-Datei immer weiter aufgebläht hat (siehe auch hier), habe ich dann doch grundsätzlich darauf verzichtet. Vielleicht ist das in den neueren Delphi-Versionen ja verbessert worden, aber mit XE mache ich das nicht mehr.

Der Vorteil gegenüber der Case-Lösung von nahpets wäre doch aber ausschließlich die einfachere Aktualisierung der Text-Datei, oder? Zur Laufzeit sollte auch TDictionary nicht schneller als In-Code-Abfrage sein (die Resource-Datei muss ja auch erstmal verarbeitet werden).

haentschman 24. Mär 2017 10:48

AW: MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen?
 
Zitat:

dass jede einzelne Verwendung von Generics die Exe-Datei immer weiter aufgebläht hat (siehe auch hier), habe ich dann doch grundsätzlich darauf verzichtet.
:gruebel: Kann ich nicht nachvollziehen. Klar muß die Funktionalität auch implementiert werden...
An meinem Beispiel (Berlin):
EXE ohne Inhalt, incl. Ressource: 12,3MB (12.977.908 Bytes) - 2505KB Verbrauch
EXE mit Inhalt, incl. Ressource, TDictionary und alle Units Generics und dem Einlesen der Textdatei: 12,3MB (12.978.468 Bytes) - 6400KB Verbrauch

...in Zeiten wo Plattenplatz keine Mangelware ist, würde ich den Overhead für die Features in Kauf nehmen. :thumb: Diese Minimalisierung der Programme hat zu DOS Zeiten noch Sinn gemacht. Jedes aktuelle Mobiltelefon hat mehr Rechenleistung als die Kapsel die auf dem Mond gelandet ist. :thumb:

Zitat:

Zur Laufzeit sollte auch TDictionary nicht schneller als In-Code-Abfrage sein (die Resource-Datei muss ja auch erstmal verarbeitet werden).
Was erwartest du denn zeitlich? :gruebel: Wenn die "Zeilen" verarbeitet werden, im Vergleich zur TStringList, ist der Unterschied nicht dramatisch. Dann aber ist der Unterschied in dem Lesen / Heraussuchen des Keys deutlich meßbar. :thumb:

nahpets 24. Mär 2017 11:57

AW: MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen?
 
Einen hätt' ich noch:

Wir bauen uns eine Komponente:
Delphi-Quellcode:
unit NMap_Map_Prefixes;

interface

uses
  SysUtils, Classes, Types;

type
  tNMap_Map_Prefixes = class(TComponent)
  private
    { Private-Deklarationen }
    fUrl           : String;
    fIncludeFile   : String;
    fIncludeUpdate : Boolean;
    fDubletten     : TStringList;
    fHasDubletten  : Boolean;
    fIncludeCreated : Boolean;
  protected
    { Protected-Deklarationen }
    procedure SetIncludeUpdate(AValue : Boolean);
    function CheckDubletten(sl : TStringList) : Boolean;
    function CreateInclude(sl : TStringList) : Boolean;
  public
    { Public-Deklarationen }
    Constructor Create(aOwner: TComponent); Override;
    Destructor Destroy; Override;
    function  GetNameFromMAC(AMac : DWord) : String;
  published
    { Published-Deklarationen }
    property Url : String read fUrl write fUrl;
    property IncludeFile : String read fIncludeFile write fIncludeFile;
    property IncludeUpdate : Boolean read fIncludeUpdate write SetIncludeUpdate;
    property Dubletten : TStringList read fDubletten write fDubletten;
    property HasDubletten : Boolean read fHasDubletten;
    property IncludeCreated : Boolean read fIncludeCreated;
  end;

procedure Register;

implementation

uses
  IdHTTP, StrUtils;

procedure Register;
begin
  RegisterComponents('Stephan', [tNMap_Map_Prefixes]);
end;

Constructor tNMap_Map_Prefixes.Create(aOwner: TComponent);
begin
  inherited;
  fDubletten  := TStringList.Create;
  fUrl        := 'http://linuxnet.ca/ieee/oui/nmap-mac-prefixes';
  fIncludeFile := 'NMap_Map_Prefixes.inc';
end;

Destructor tNMap_Map_Prefixes.Destroy;
begin
  fDubletten.Free;
  inherited;
end;

function MyCompare(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := CompareText(Copy(List[Index1],8,4096), Copy(List[Index2],8,4096));
end;

function tNMap_Map_Prefixes.GetNameFromMAC(AMac : DWord) : String;
begin
  case AMac of
    $000000 : Result := '<unbekannt>';
{$I NMap_Map_Prefixes.inc}
  else
    Result := '<unbekannt>';
  end;
end;

function tNMap_Map_Prefixes.CheckDubletten(sl : TStringList) : Boolean;
var
          s : String;
          i : Integer;
begin
  fDubletten.Clear;
  sl.Sort;
  s := '';
  for i := 0 to sl.Count - 1 do begin
    if s = Copy(sl[i],1,6) then begin
       fDubletten.Add(Format('Dublette %s',[Copy(sl[i],1,6)]));
       fDubletten.Add(Format('Dublette %s',[Copy(sl[i - 1],8,4096)]));
       fDubletten.Add(Format('Dublette %s',[Copy(sl[i],8,4096)]));
    end;
    s := Copy(sl[i],1,6);
  end;
  Result := fDubletten.Count <> 0;
end;

procedure tNMap_Map_Prefixes.SetIncludeUpdate(AValue : Boolean);
var
          idHTTP   : TIDHttp;
          sl       : TStringList;
          slInclude : TStringList;
begin
  fIncludeUpdate := AValue;
  sl             := TStringList.Create;
  slInclude      := TStringList.Create;
  idHTTP         := tIDHTTP.Create(Self);
  sl.Text        := idHTTP.Get(fUrl);
  fIncludeCreated := CreateInclude(sl);
  fHasDubletten  := CheckDubletten(sl);
  idHTTP.Free;
  slInclude.Free;
  sl.Free;
  fIncludeUpdate := False;
end;

function tNMap_Map_Prefixes.CreateInclude(sl : TStringList) : Boolean;
var
          s        : String;
          sCase    : String;
          i        : Integer;
          slInclude : TStringList;
begin
  DeleteFile(fIncludeFile);
  fIncludeCreated := false;
  fHasDubletten  := false;
  slInclude      := TStringList.Create;
  sl.CustomSort(MyCompare);
  s    := '';
  sCase := '';
  for i := 0 to sl.Count - 1 do begin
    if s <> AnsiReplaceText(Copy(sl[i],8,4096),'''',''''' ') then begin
      if Trim(s) <> '' then begin
        slInclude.Add(Format('   %s: Result := ''%s'';',[sCase,s]));
      end;
      s := AnsiReplaceText(Copy(sl[i],8,4096),'''',''''' ');
      if Trim(s) <> '' then begin
        sCase := '$' + Copy(sl[i],1,6);
      end;
    end else begin
      if Length(sCase) = 70 then begin
        slInclude.Add(Format('   %s,',[sCase]));
        sCase := '';
      end;
      if sCase = '' then begin
        sCase := '$' + Copy(sl[i],1,6);
      end else begin
        sCase := sCase + ', $' + Copy(sl[i],1,6);
      end;
    end;
  end;
  slInclude.Add(Format('   %s: Result := ''%s'';',[sCase,s]));
  slInclude.SaveToFile(fIncludeFile);
  slInclude.Free;
  Result := FileExists(fIncludeFile);
end;

end.
Für {$I NMap_Map_Prefixes.inc} benötigen wir erstmal eine leere Datei.

Komponente auf's Formular pappen.
Bei der Eigenschaft IncludeFile den Dateinamen incl. Pfad für NMap_Map_Prefixes.inc eingeben.
Falls eine andere Url für die Datei http://linuxnet.ca/ieee/oui/nmap-mac-prefixes genutzt werden soll, kann diese in der Eigenschaft Url eingetragen werden. Der Aufbau der Datei muss natürlich identisch sein.

Doppelklick auf den Wert der Eigenschaft IncludeUpdate.

Jetzt arbeitet die IDE ein bisserl. Der Wert der Eigenschaft ändert sich nicht.

Sofern die Includedatei erstellt werden konnte, wird die Eigenschaft IncludeCreated auf True gesetzt.

Wurden doppelte Werte für die Case-Label gefunden, so wird die Eigenschaft HasDubletten auf True gesetzt.

Die Dubletten werden in der Eigenschaft Dubletten aufgeführt und können mit 'nem Doppelklick auf den Wert der Eigenschaft angezeigt werden.

Anschließend das Projekt neu erzeugen und ggfls. die Label-Dubletten in der Includedatei bereinigen.

Oder kurz:

Die IDE erzeugt uns zur Entwicklungszeit den von uns benötigten Quelltext.

Benutzen können wir ihn im Programm dann z. B. so:
Delphi-Quellcode:
ShowMessage(NMap_Map_Prefixes.GetNameFromMAC($049573));


PS.: Der Spass wurde mit Delphi 7 erstellt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:29 Uhr.
Seite 2 von 2     12   

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