Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Mit IP-Adressen rechnen... (https://www.delphipraxis.net/115242-mit-ip-adressen-rechnen.html)

SaltJohn 9. Jun 2008 05:49


Mit IP-Adressen rechnen...
 
Hallo, ich möchte gerne einer als String vorhandenen IP-Adresse einen Offset geben sprich:

aus 192.168.0.1 wird 192.168.0.101

Ich denke mal ich muss irgendwie an das letzte oktett kommen, dann strgtoint und dann 100 addieren.
bloß wie mache ich das am sinnvollsten?

Sharky 9. Jun 2008 06:08

Re: Mit IP-Adressen rechnen...
 
Hai SaltJohn,

erst einmal: "Herzlich Willkommen in der Delphi-PRAXiS" :hello:

Solch einen String kannst Du recht einfach mit Delphi-Referenz durchsuchenPos und Delphi-Referenz durchsuchenCopy bzw. mit Delphi-Referenz durchsuchenPosEx aufteilen.
Danach einfach die Teilstrings mit StrToInt umwandeln, addieren und wieder zurück wandeln.

soulies 9. Jun 2008 06:10

Re: Mit IP-Adressen rechnen...
 
hoi,

wenn du die IP auch anzeigst kannst Du JvIPAddress nehmen [JEDI]
dort kannst du bequem auf alle einzelnen Bereiche zugreifen.

Mit ner Stringlist sollte es auch klappen -> Delimiter='.' und dann Wert 4 zum rechnen.

cya

RWarnecke 9. Jun 2008 06:56

Re: Mit IP-Adressen rechnen...
 
Hi SaltJohn,

auch von mir ein herzliches Willkommen in der Delphi-Praxis. :cheer:

Um den String aufzuteilen habe ich mal diese ganz nützliche Funktion im Internet gefunden :
Delphi-Quellcode:
type
  ArrOfStr = array of string;

function Explode(var a: ArrOfStr; Border, S: string): Integer;
var
  S2: string;
begin
  Result := 0;
  S2 := S + Border;
  repeat
    SetLength(A, Length(A) + 1);
    a[Result] := Copy(S2, 0, Pos(Border, S2) - 1);
    Delete(S2, 1, Length(a[Result] + Border));
    Inc(Result);
  until S2 = '';
end;

marabu 9. Jun 2008 07:01

Re: Mit IP-Adressen rechnen...
 
Moin,

ab und zu werden auch die vom Betriebssystem vorgesehenen Routinen benutzt:

Delphi-Quellcode:
uses
  WinSock;

var
  inAddr: TINAddr;
  s: string;

begin
  inAddr.S_addr := inet_addr('192.168.0.1');
  with inAddr.S_un_b do
    s_b4 := #101;
  s := inet_ntoa(inAddr);
  ShowMessage(s);
end;
Freundliche Grüße

SaltJohn 9. Jun 2008 08:21

Re: Mit IP-Adressen rechnen...
 
Zunächst recht vielen Dank für die nette Aufnahme in Eurem Forum :) jetzt zu den Vorschlägen. Also ich hab mir mal instinktiv den kürzesten Code geschnappt sprich den von Marabu.

Der Code funktioniert auch recht gut nur leider ist die IP in meinem Programm von Anweder zu Anwender verschieden und somit ist auch das 4. Oktett variabel. Dehalb muss ich es noch irgendwie schaffen das
4. Oktett der zuvor eingegebenen IP-Adresse auszulesen um dieses gegebenfalls in eine Zahl umwandeln und mit einem beliebigen Offset von z.B. 100 zu versehen.

marabu 9. Jun 2008 08:25

Re: Mit IP-Adressen rechnen...
 
Du schaffst das:

Delphi-Quellcode:
// ...
  with inAddr.S_un_b do
    s_b4 := Chr(Ord(s_b4) + 100);
// ...

Sharky 9. Jun 2008 08:37

Re: Mit IP-Adressen rechnen...
 
Zitat:

Zitat von SaltJohn
... und mit einem beliebigen Offset von z.B. 100 zu versehen.

Wobei Du in diesem Fall auch noch eine Prüfung einbauen solltest. Nicht das im 4. Oktett auf einmal ein Wert > 254 steht. (Subnetting jetzt mal aussen vor gelassen)

SaltJohn 9. Jun 2008 08:59

Re: Mit IP-Adressen rechnen...
 
danke Marabu es läuft soweit allerdings möchte ich zum Schluss noch eine zweite Adresse mit Offset generieren und das klappt noch nicht. Es erscheint dann eine völlig andere. Womöglich muss ich noch reservierten Speicher freigeben oder so.

Delphi-Quellcode:
procedure TForm1.Button5Click(Sender: TObject);
    var  inAddr: TINAddr;
          IPAdresse : string;
          IPAdresseOffset1 : string;
          IPAdresseOffset2 : string;
begin
    IPAdresse := Edit1.Text;
    inAddr.S_addr := inet_addr(PChar(IPAdresse));
    with inAddr.S_un_b do
    s_b4 := Chr(Ord(s_b4) + 100);
    IPAdresseOffset1 := inet_ntoa(inAddr);
    Edit2.Text := IPAdresseOffset1;
    with inAddr.S_un_b do
    s_b4 := Chr(Ord(s_b4) + 200);
    IPAdresseOffset2 := inet_ntoa(inAddr);
    Edit3.Text := IPAdresseOffset2;
end;
Wenn du mir kurz erklärst was dein Code eigentlich so macht komme ich evtl. alleine drauf :)


Edit:

@Stephan B. So eine Prüfung ist scheinbar schon vorhanden denn sobald 255 überschritten wird gehts wieder mit 0 aufwärts los :)

Edit2:
Habe es jetzt soweit hinbekommen. Wenn der Offset2 bsp. 200 sein soll muss ich ja einfach nur nochmal 100 zum 1. addieren. Jedoch verstehe ich den eigentlichen Ablauf immer noch nicht.


Delphi-Quellcode:
//...
with inAddr.S_un_b do
    s_b4 := Chr(Ord(s_b4) + 100);
    IPAdresseOffset2 := inet_ntoa(inAddr);
    Edit3.Text := IPAdresseOffset2;
//...

marabu 9. Jun 2008 13:50

Re: Mit IP-Adressen rechnen...
 
Hallo,

die beiden Funktionen zur Wandlung zwischen String- und Binärdarstellung einer IP-Adresse kannst du ja in der Hilfe nachschlagen, also scheinst du ein Verständnisproblem mit der eigentlichen Adressumsetzung zu haben.

Delphi-Quellcode:
// ...
  with inAddr.S_un_b do
    s_b4 := Chr(Ord(s_b4) + 200);
// ...
Der Typ TInAddr wird mehrfach redefiniert, so dass man seine vier Bytes auf verschiedene Weise ansprechen kann. Schau mal in die Unit WinSock - oder wenn du diese nicht hast:

Delphi-Quellcode:
type
  {$EXTERNALSYM SunB}
  SunB = packed record
    s_b1, s_b2, s_b3, s_b4: u_char;
  end;

  {$EXTERNALSYM SunW}
  SunW = packed record
    s_w1, s_w2: u_short;
  end;

  PInAddr = ^TInAddr;
  {$EXTERNALSYM in_addr}
  in_addr = record
    case integer of
      0: (S_un_b: SunB);
      1: (S_un_w: SunW);
      2: (S_addr: u_long);
  end;
  TInAddr = in_addr;
Freundliche Grüße

SaltJohn 10. Jun 2008 10:10

Re: Mit IP-Adressen rechnen...
 
Ok ein wenig blicke ich durch. Man kann also über WinSock die einzelnen Oktetts des IP-Strings ansprechen.

Delphi-Quellcode:
s_b4 := Chr(Ord(s_b4) + 100);  // ASCIIcode von(Binärzahl des 4.Oktetts + 100(dez))
Korrigiere mich bitte wenn falsch liegen.

Tod787 9. Jul 2008 09:51

Re: Mit IP-Adressen rechnen...
 
Hi, habe da etwas ähnliches vor.
Ich würde gerne die Wahl des zu ändernden Byte variabel lassen also der Funktion einen Eingabeparameter geben um Byte 1-4 auszuwählen.

Eigentlich bräuchte ich doch nur eine Möglichkeit s_b4 mit einer Verknüpfung variabel zu machen( Bsp. s_b + Übergabeparameter). Bloss wie wandle ich die Variable um?
Habe im Code unten mal die Funktion mit Parameter. "s_bx" soll hier die Variable sein die mit dem Übergabeparameter das richtige Byte der IP ansprechen soll.


Delphi-Quellcode:
procedure TForm1.Button5Click(i: Integer);
var  inAddr: TINAddr;
      s_bx : string;
begin
      IPAdresse := Edit1.Text;
      inAddr.S_addr := inet_addr(PChar(IPAdresse));
      s_bx := 's_b'+intToStr(i);        // HIER DER STRING WELCHER NOCH UMGEWANDELT WERDEN MUSS
      with inAddr.S_un_b do
         s_bx := Chr(Ord(s_bx) + FOffset);        
      IPAdresseOffset := inet_ntoa(inAddr);    
end;
Am Besten wäre es natürlich wenn es etwas wie Gibt es etwas wie StringToxxx(s_bx) geben würde :)

Edit: Eine Möglichkeit wäre natürlich das mit Case of... zu machen

SaltJohn 10. Jul 2008 05:53

Re: Mit IP-Adressen rechnen...
 
Hi Tod787, Sorry aber da kann ich dir nicht weiterhelfen. Höchstens mit einer Case...of Anwendung aber da bist du ja schon selbst draufgekommen :)

sirius 10. Jul 2008 08:13

Re: Mit IP-Adressen rechnen...
 
eine IPv4 Adresse ist nix anderes als eine 32bit Zahl (Cardinal)
Delphi-Quellcode:
function add2Addr(addr:String; Pos:Byte; count:Integer):string;
var inAddr:cardinal;
begin
  inAddr:=inet_addr(PChar(Addr)); //Umwandeln in Integer (Achtung! ist Big Endian)
  Pos:=pos*8; //pos*8bit ergibt das gesuchte Byte
  inc(inAddr,count shl pos); addieren und dabei count an die richtige Position schieben
  result:=inet_ntoa(in_Addr(inAddr)); //zurückwandeln
end;
Pos = 0..3 (0 ist die erste Stelle 3 die Letzte)

Tod787 16. Jul 2008 08:18

Re: Mit IP-Adressen rechnen...
 
Danke klappt wirklich gut soweit. Was mich noch beschäftigt ist eine Art Überlaufkontrolle einzurichten. Ich meine wenn der Offset zu hoch gewählt wurde und die Zahl über 254 geht ist es ja jetzt so dass bei der Umwandlung einfach wieder bei 0 angefangen wird.

Edit: Ich müsste doch quasi nur ab dem gewünschten Oktett 8 bits zählen und deren Wert mit 255 vergleichen. Bloß wie komme ich an die 8 Bit ran?

Was mich auch wundert ist dass die Zahl 255 nicht erreicht werden kann.

sirius 16. Jul 2008 14:56

Re: Mit IP-Adressen rechnen...
 
Welche Lösung hast du denn jetzt gewählt?

SaltJohn 16. Jul 2008 18:03

Re: Mit IP-Adressen rechnen...
 
Also ich würde die letzte nehmen

Edit: Die anderen sind aber auch ok ;)

sirius 16. Jul 2008 19:52

Re: Mit IP-Adressen rechnen...
 
InAddr ist eine 32-Bit-ZAhl
Die IP 255.255.255.255 wird als $FFFFFFFF dargetsellt
IP 255.0.0.0 ist $FF000000
IP 0.0.0.255 ist $000000FF
usw. usf.
Und damit kannst du jetzt rechnen.

Wenn du zu Beispiel die erste Stelle haben willst, dann machst du
(inAddr and $FF000000) shr (3*8)
bzw
(inAddr and ($FF shl (3*8)) shr (3*8)
Anstatt der 3 kannst du dann die anderen Positionen einsetzen.


Edit: Verdammt aus "8)" wurde ja ein Smiley

Tod787 17. Jul 2008 09:20

Re: Mit IP-Adressen rechnen...
 
Hab das leider nur halb verstanden. Habe mir eine Lösung mit deiner Methode überlegt allerdings funktioniert diese nur mit dem ersten Byte meiner IP-Adresse.

Delphi-Quellcode:
var
    inAddr: cardinal;
    inAddr_bkup: cardinal;
    Originalbyte: Integer;
    Offsetbyte: integer;
   
begin
    inAddr := inet_addr(PChar(FAdr));  // Umwandeln in Zahl
    inAddr_bkup := inAddr;            // Zahl merken
    pos := pos * 8;                  // pos*8(bit) ergibt das gesuchte Byte
    inc(inAddr,count shl pos);       // addieren und dabei den Offset in Byte schieben
    Originalbyte := (inAddr_bkup and $FF000000) shr (pos);    // Wert des Originalbyte bestimmen
    Offsetbytet := ((inAddr and $FF000000) shr (pos));     // Wert des Bytes mit Offset bestimmen
    if Offsetbyte = Originalbyte + count then   // Wenn Offsetbyte = Originalbyte+Offset
      result := inet_ntoa(in_Addr(inAddr))     // zurückwandeln
    else showmessage('Offset zu groß')         // sonst Fehlermeldung
end;
Edit:

Es hat doch noch funktioniert :)

mit deiner zweiten Methode geht

Delphi-Quellcode:
var
    inAddr: cardinal;
    inAddr_bkup: cardinal;
    Originalbyte: Integer;
    Offsetbyte: integer;
   
begin
    inAddr := inet_addr(PChar(FAdr));  // Umwandeln in Zahl
    inAddr_bkup := inAddr;            // Zahl merken
    pos := pos * 8;                  // pos*8(bit) ergibt das gesuchte Byte
    inc(inAddr,count shl pos);       // addieren und dabei den Offset in Byte schieben
   Originalbyte := (inAddr_bkup and ($FF shl (pos)) shr (pos)); // Wert des Originalbyte bestimmen    
    Originalbyte := (inAddr and ($FF shl (pos)) shr (pos));     // Wert des Bytes mit Offset bestimmen    
    if Offsetbyte = Originalbyte + count then   // Wenn Offsetbyte = Originalbyte+Offset
      result := inet_ntoa(in_Addr(inAddr))     // zurückwandeln
    else showmessage('Offset zu groß')         // sonst Fehlermeldung
end;
Ist aber bestimmt nicht so gelöst wie du das dachtest, oder?

sirius 17. Jul 2008 21:50

Re: Mit IP-Adressen rechnen...
 
Ich hatte nicht so weit gedacht. Aber sieht doch gut aus.

Ich hätte wahrscheinlich vorm Addieren überprüft. Es gibt Dutzende Wege hier. Und solange das Ergebnis stimmt.....


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:42 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