AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi MAC-Hersteller-Zuordnung bzw. Wie mit einem sehr großen Datensatz umgehen?

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

Ein Thema von CodeX · begonnen am 23. Mär 2017 · letzter Beitrag vom 24. Mär 2017
Antwort Antwort
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 23. Mär 2017, 23:05
Oh wow, ja das ist super!
Irgendwie habe ich mich gedanklich in andere Richtungen verrannt. DANKE!!
Die Dubletten sind nicht schlimm. Die werden dann eben zusammengefasst. Kann ja nichts dafür, dass die so vergeben wurden.

Hast Du Dir da extra einen Parser dafür geschrieben?
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.

Geändert von CodeX (23. Mär 2017 um 23:31 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#2

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

  Alt 23. Mär 2017, 23:25
Parser wäre da wohl deutlich übertrieben

Mein Editor unterstützt die Nutzung von Pascal-Script.

Und dafür hab' ich mir halt folgenden Quelltext zusammengedaddelt:
Delphi-Quellcode:
program Test;
var
        i : Integer;
        k : Integer;
        s : String;
        sCase : String;

procedure Dubletten;
begin
  GetSelText;
  s := '';
  for i := 0 to SelText.Count - 1 do begin
    if s = Copy(SelText[i],1,6) then begin
       WriteLn(Format('Dublette %s',[Copy(SelText[i],1,6)]));
       WriteLn(Format('Dublette %s',[Copy(SelText[i - 1],8,4096)]));
       WriteLn(Format('Dublette %s',[Copy(SelText[i],8,4096)]));
    end;
    s := Copy(SelText[i],1,6);
  end;
end;

procedure CaseErstellen;
begin
  GetSelText;
  k := 0;
  s := AnsiReplaceText(Copy(SelText[0],8,4096),'''',''''' ');
  s := '';
  sCase := '';
  for i := 0 to SelText.Count - 1 do begin
    if s <> AnsiReplaceText(Copy(SelText[i],8,4096),'''',''''' ') then begin
      WriteLn(Format(' %s: Result := ''%s'';',[sCase,s]));
      s := AnsiReplaceText(Copy(SelText[i],8,4096),'''',''''' ');
      sCase := '$' + Copy(SelText[i],1,6);
    end else begin
      if Length(sCase) = 70 then begin
        WriteLn(Format(' %s,',[sCase]));
        sCase := '';
      end;
      if sCase = 'then sCase := '$' + Copy(SelText[i],1,6) else sCase := sCase + ', $' + Copy(SelText[i],1,6);
    end;
  end;
  WriteLn(Format(' %s: Result := ''%s'';',[sCase,s]));
end;

procedure InitErstellen;
begin
  GetSelText;
  k := 0;
  for i := 0 to SelText.Count - 1 do begin
    if (i mod 500 = 0) then begin
      if i > 0 then begin
        WriteLn('end;');
        WriteLn('');
      end;
      Output.Add(Format(' procedure Init%0.3d;',[k]));
      WriteLn(Format('procedure tNMap_Mac_List.Init%0.3d;',[k]));
      WriteLn('begin');
      k := k + 1;
    end;
    WriteLn(Format(' fHex.Add(''%s''); fName.Add(''%s'');',[Copy(SelText[i],1,6),AnsiReplaceText(Copy(SelText[i],8,4096),'''',''''' ')]));
  end;
  WriteLn('end;');
end;

begin
  // InitErstellen;
  // CaseErstellen;
  Dubletten;
end.
GetSelText holt den im Editor markierten Text, SelText ist 'ne Stringliste mit eben diesem Text und WriteLn schreibt in ein Ausgabefenster (ein TMemo).

Der Rest ist "handelsübliches" Delphi und einbisserl Schreibarbeit

Wenn Du das auf Delphi umbauen möchtest, musst Du halt noch zwei Stringlisten machen.

Delphi-Quellcode:
SelText := TStringList.Create;
Ausgabe := TStringList.Create;
SelText.LoadFromFile('nmap-mac-prefixes.txt');
// Statt WriteLn(...); halt Ausgabe.Add(...);
Ausgabe.SaveToFile('nmap_mac_prefixes.inc');
Ausgabe.Free;
SelText.Free;
Und damit dürfte es mit marginaler Nacharbeit möglich sein, ggfls. aus 'ner neuen nmap-mac-prefixes.txt den Case-Teil zu generieren.

Für die Dublettenprüfung muss die Datei nmap-mac-prefixes.txt ab der 1. Spalte sortiert sein, für das Erstellen des Case-Teiles und die erste Stringlistenvariante ab der 8. Spalte.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#3

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

  Alt 24. Mär 2017, 07:08
Das ist doch eine typische Datenbankanwendung.
Die Daten normalisieren, sprich zwei Tabellen erstellen und dann mit binärer Suche dadurch hüpfen.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.436 Beiträge
 
Delphi 12 Athens
 
#4

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

  Alt 24. Mär 2017, 07:30
Moin...

Wenn es keine DB hat, dann würde ich die Textdatei als Ressource kompilieren. Nach dem Programmstart würde ich die Ressource einlesen. Für die Lagerung der Informationen käme ein TDictionary<string, string> in Frage. Beim Einlesen wird aus jeder Zeile aus den ersten 6 Zeichen der Key generiert in der Rest ist das Value. Die Dupletten kannst du schon beim Einlesen handeln. Wenn der Key existiert dann den Value an den bestehenden Value hängen.
...fertsch.

Vorteil:

1. Liste.LoadFromFile('nmap-mac-prefixes.txt'); ist nicht notwendig da die Textdatei zur Laufzeit nicht beigelegt werden muß...wird beim Erzeugen einkompiliert.
2. Keine Änderung des Quelltextes bei Inhaltsänderungen der TXT...einfach neu kompilieren.
3. Ein Dictionary ist dafür da was aus einer "Liste" herauszusuchen...deutlich schneller als TStringlist.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes, System.Generics.Collections, System.Generics.Defaults,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FDictionary: TDictionary<string, string>;
    procedure ReadFile;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  FDictionary := TDictionary<string, string>.Create;
  ReadFile;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FDictionary.Free;
end;

procedure TForm1.ReadFile;
var
  I: Integer;
  Content: TStringList;
  TextStream: TResourceStream;
  CurrentRowKey: string;
  CurrentRowValue: string;
begin
  FDictionary.Clear;
  Content := TStringList.Create;
  try
    TextStream := TResourceStream.Create(HInstance, 'Content', PWideChar('ContentFile'));
    try
      Content.LoadFromStream(TextStream);
      for I := 0 to Content.Count - 1 do
      begin
        CurrentRowKey := Copy(Content[I], 1, 6);
        if not FDictionary.TryGetValue(CurrentRowKey, CurrentRowValue) then
        begin // einfügen
          CurrentRowValue := Copy(Content[I], 8, Length(Content[I]) + 8);
          FDictionary.Add(CurrentRowKey, CurrentRowValue);
        end
        else
        begin // Key zusammensetzen bei Duplikaten
          CurrentRowValue := Copy(Content[I], 8, Length(Content[I]) + 8);
          FDictionary.AddOrSetValue(CurrentRowKey, FDictionary.Items[CurrentRowKey] + '; ' + CurrentRowValue);
        end;
      end;
    finally
      TextStream.Free;
    end;
  finally
    Content.Free;
  end;
end;

end.
RC Datei Inhalt:
Zitat:
Content ContentFile "D:\Blubb\nmap-mac-prefixes.txt"
... als RC Datei ins Projekt. (Pfadangaben anpassen)
Angehängte Grafiken
Dateityp: png Resccource.png (58,0 KB, 9x aufgerufen)
Angehängte Dateien
Dateityp: zip Muster.zip (462,7 KB, 4x aufgerufen)

Geändert von haentschman (24. Mär 2017 um 11:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

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

  Alt 24. Mär 2017, 08:00
Moin...

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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

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

  Alt 24. Mär 2017, 07:31
War auch meine erste Idee. Nur er will alles in einer Datei weiter geben ohne (Installation.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.436 Beiträge
 
Delphi 12 Athens
 
#7

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

  Alt 24. Mär 2017, 09:05
Zitat:
War auch meine erste Idee. Nur er will alles in einer Datei weiter geben ohne (Installation.
bezog sich das auf meinen Beitrag oder die DB Lösung?
Zitat:
Zu 1.: Als Textdatei als Ressource einkompilieren und zur Abfrage temporär entpacken.
...das hatte ich übersehen.
Zitat:
Wäre interessant, was schneller wäre Tdictionary oder der "DB-Ansatz"
...deutlich TDictionary.

Geändert von haentschman (24. Mär 2017 um 09:23 Uhr)
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 24. Mär 2017, 09:50
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.

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).
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.436 Beiträge
 
Delphi 12 Athens
 
#9

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

  Alt 24. Mär 2017, 10:48
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.
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. 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.

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

Geändert von haentschman (24. Mär 2017 um 11:07 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 23:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz