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
nahpets
(Gast)

n/a Beiträge
 
#1

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

  Alt 23. Mär 2017, 22:56
Mann, Du bist aber anspruchsvoll

Ok: Luckies Caseansatz könnte dann so aussehen:
Delphi-Quellcode:
unit nmap_mac_prefixes;

interface

  function GetMac(AMac : Integer) : String;

implementation

function GetMac(AMac : Integer) : String;
begin
  case AMac of
    $30F33A: Result := '+plugg srl';
    $700258: Result := '01DB-Metravib';
    $C49313: Result := '100fio networks';
    $080024: Result := '10NET/DCA';
    $000B10: Result := '11wave Technonlogy';
    $A85EE4: Result := '12Sided';
    $005029: Result := '1394 Printer Working Group';
    $00A02D: Result := '1394 Trade Association';
    $001974: Result := '16063';
    $003070: Result := '1Net';
    $54369B: Result := '1Verge Internet';
    $443719: Result := '2 Save Energy';
    $0011B2: Result := '2001';
    $0025C3: Result := '21168';
    $EC9681: Result := '2276427 Ontario';
    $001387: Result := '27M';
    $000761: Result := '29530';
    $28F358: Result := '2C - Trifonov';
    $3C3F51: Result := '2CRSI';
    $0016A9: Result := '2EI';
    $B8B7D7: Result := '2GIG';
    $001B8A: Result := '2M';
    $001929: Result := '2M2B Montadora de Maquinas Bahia Brasil';
    $7C1EB3: Result := '2N TELEKOMUNIKACE a.s';
    $F82C18, $28162E, $383BC8, $94C150, $001288, $002456, $60FE20, $982CBE,
    $0022A4, $002650, $34EF44, $00183F, $002351, $00D09E, $001FB3, $DC7FA4,
    $749DDC, $00253C, $0019E4, $001EC7, $F81897, $640F28, $C0830A, $000D72,
    $3CEA4F, $00217C, $60C397, $001D5A, $B8E625, $B0E754, $14EDBB, $001AC4,
    $001B5B, $001495: Result := '2Wire';

... und viele weitere Zeilen ...
... vollständig im Anhang ...

    $000689: Result := 'yLez';
    $8CC7D0: Result := 'zhejiang ebang';
    $30F31D, $28FF3E, $78312B, $DC028E, $4C09B4, $601466, $84742A, $E47723,
    $30D386, $2C26C5, $601888, $B805AB, $8C7967, $A8A668, $744AA4, $901D27,
    $F4B8A7, $C864C7, $4C16F1, $688AF0, $709F2D, $789682, $4CAC0A, $D0154A,
    $4CCBF5, $48282F, $FCC897, $B4B362, $CC1AFA, $540955, $300C23, $48A74E,
    $B49842, $346987, $004A77, $344DEA, $F41F88, $343759, $344B50, $F084C9,
    $001E73, $88D274, $B075D5, $986CF5, $C87B5B, $F46DE2, $702E22, $AC6462,
    $981333, $CC7B35, $2C957F, $C4A366, $681AB2, $34DE34, $D855A3, $A0EC80,
    $208986, $D437D7, $64136C, $FC2D5E, $0C1262, $083FBC, $94A7B7, $EC1D7F,
    $002293, $D87495, $38D82F, $749781, $08181A, $D476EA, $1844E6, $9CA9E4,
    $146080, $F8DFA8, $9CD24B, $18686A, $002512, $D4C1C8, $E07C13, $F8A34F,
    $A091C8, $10D0AB, $143EBF, $3CDA2A, $0015EB, $74A78E, $98F537, $98F428,
    $8CE081, $78C1A7, $5422F8, $54BE53, $6C8B2F, $8CE117, $0026ED, $44F436,
    $6CA75F, $EC237B, $F4E4AD, $34E0CF, $0019C6, $EC8A4C, $384608, $6073BC,
    $D071C4, $90C7D8, $90D8F3, $E0C3F3, $78E8B6, $74B57E, $D0608C, $D05BA8,
    $D058A8, $24C44A, $689FF0, $A47E39, $049573: Result := 'zte';
  else
    Result := '<unbekannt>';
  end;
end;

end.
Das ist allerdings nicht kompilierbar, wegen doppelter Case-Label. So ist z. B. 080030 nicht eindeutig, sondern wird von drei Firmen genutzt: Cern, Network und Royal Melbourne Inst Of. Da wirst Du Dir dann wohl noch eine andere Lösung suchen müssen

Allerdings halten sich die Dubletten im Rahmen, folgende hab' ich finden können:
Code:
0001C8 Conrad und Thomas Conrad
080030 Cern, Network und Royal Melbourne Inst Of
Dafür wäre der Aufruf aber deutlich einfacher:ShowMessage(GetMac($000019));

Geändert von nahpets (21. Nov 2017 um 16:41 Uhr)
  Mit Zitat antworten Zitat
CodeX

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

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
 
#3

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
 
#4

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
 
#5

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
 
#6

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

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
 
#8

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
 
#9

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
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:40 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