Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Prüfen, ob String eine gültige IPv6-Adresse ist (https://www.delphipraxis.net/130420-pruefen-ob-string-eine-gueltige-ipv6-adresse-ist.html)

jaenicke 8. Mär 2009 19:01

Re: Prüfen, ob String eine gültige IPv6-Adresse ist
 
Ach, :: kann auch nur ein Block mit 0 sein. :wall:
Ok, dann so, sind nur zwei Zahlen anders, aber ich poste es mal trotzdem komplett nochmal:
Delphi-Quellcode:
// Autor: Sebastian Jänicke (jaenicke @ delphipraxis.net)
// [url]http://www.delphipraxis.net/post1011159.html#1011273[/url]
function SJCheckIPv6(Value: String): Boolean;
type
  CheckIPState = (cisNone, cisDelim, cisDelimStart, cisDoubleDelim,
    cisHex1, cisHex2, cisHex3, cisHex4);
var
  DoubleDelim: Boolean;
  i, CurBlock: Integer;
  CurState: CheckIPState;
begin
  Result := False;
  DoubleDelim := False;
  CurState := cisNone;
  CurBlock := 0;
  for i := 1 to Length(Value) do
    case Value[i] of
      'a'..'f', '0'..'9':
        case CurState of
          cisNone, cisDelim:
            begin
              CurState := cisHex1;
              Inc(CurBlock);
              if CurBlock > 8 then
                Exit; // mehr als 8 Blöcke geht nicht
            end;
          cisDelimStart:
            Exit; // ein einzelnes : am Anfang geht nicht
          cisDoubleDelim:
            begin
              CurState := cisHex1;
              Inc(CurBlock, 2);
              if CurBlock > 8 then
                Exit; // :: steht für mind. 1 Block, mehr als 8 geht nicht
              DoubleDelim := True;
            end;
          cisHex1:
            CurState := cisHex2;
          cisHex2:
            CurState := cisHex3;
          cisHex3:
            CurState := cisHex4;
          cisHex4:
            Exit; // Mehr als 4 hexadezimale Zeichen hintereinander geht nicht
        end;
      ':':
        case CurState of
          cisNone:
            CurState := cisDelimStart;
          cisDelim:
            if DoubleDelim or (CurBlock > 7) then
              Exit // zweimal :: geht nicht,
                   // außerdem steht :: für mind. 1 Block, mehr als 8 geht nicht
            else
              CurState := cisDoubleDelim;
          cisDelimStart:
            CurState := cisDoubleDelim;
          cisDoubleDelim:
            Exit; // drittes : hintereinander ist nicht erlaubt
          cisHex1, cisHex2, cisHex3, cisHex4:
            CurState := cisDelim;
        end;
    else
      Exit; // ungültiges Zeichen
    end;
  Result := (CurState <> cisDelim) and ((CurBlock = 8) or DoubleDelim);
end;
// EDIT:
Kommentare aktualisiert
// EDIT2:
Jedenfalls siehst du, dass das auf diese Weise nicht nur schnell geschrieben war (vorhin 10 Minuten oder so), sondern auch sehr einfach angepasst werden kann. :mrgreen:

CodeX 8. Mär 2009 20:59

Re: Prüfen, ob String eine gültige IPv6-Adresse ist
 
Sieht gut aus. Hab mal alle möglichen Test-Fälle durchgespielt und es scheint alles zu klappen. :)
Wäre imho was für die Library.

jaenicke 8. Mär 2009 21:33

Re: Prüfen, ob String eine gültige IPv6-Adresse ist
 
Wie gesagt: Es fehlt z.B. noch die Behandlung einer IPv4 in einer IPv6 Adresse.

Ich checke das noch mit dem entsprechenden Standard RFC 2373 (26 DIN A4 Seiten, aber bin gleich durch^^), integriere vielleicht noch eine Unterscheidung zwischen Adresstypen und die Integration einer IPv6 Adresse in eine URL nach RFC 2732, und dann stelle ich es in die Library. ;-)

jaenicke 9. Mär 2009 02:19

Re: Prüfen, ob String eine gültige IPv6-Adresse ist
 
So, für die IP sollten jetzt alle Fälle des Standards erkannt werden.

Der aktuelle Quelltext befindet sich auch hier als Vorschlag für die Library: :zwinker:
http://www.delphipraxis.net/internal....php?p=1011376

Delphi-Quellcode:
// Autor: Sebastian Jänicke (jaenicke @ delphipraxis.net)
// [url]http://www.delphipraxis.net/post1011159.html#1011159[/url]
function SJCheckIPv6(Value: AnsiString): Boolean;

  function CheckIPv4(Start: Integer): Boolean;
  var
    i, CurValue, DotCount: Integer;
    CurDot: Boolean;
  begin
    Result := False;
    CurValue := 0;
    DotCount := 0;
    CurDot := False;
    for i := Start to Length(Value) do
      case Value[i] of
        '0'..'9':
          begin
            CurValue := CurValue * 10 + Ord(Value[i]) - 48;
            CurDot := False;
          end;
        '.':
          if (CurValue > 255) or CurDot or (i = Start) then
            Exit
          else
          begin
            CurValue := 0;
            CurDot := True;
            Inc(DotCount);
          end;
      else
        Exit;
      end;
    Result := (DotCount = 3) and (CurValue <= 255) and not CurDot;
  end;

type
  TCheckIP6State = (cisNone, cisColon, cisColonStart, cisDoubleColon,
    cisHex1, cisHex2, cisHex3, cisHex4);
var
  DoubleColon: Boolean;
  i, CurBlock: Integer;
  CurState: TCheckIP6State;

  function CheckHexChars: Boolean;
  begin
    Result := True;
    case CurState of
      cisNone, cisColon:
        begin
          CurState := cisHex1;
          Inc(CurBlock);
          if CurBlock > 8 then
            Result := False; // mehr als 8 Blöcke geht nicht
        end;
      cisColonStart:
        Result := False; // ein einzelnes : am Anfang geht nicht
      cisDoubleColon:
        begin
          CurState := cisHex1;
          Inc(CurBlock, 2);
          if CurBlock > 8 then
            Result := False; // :: steht für mind. 1 Block, mehr als 8 geht nicht
        end;
      cisHex1:
        CurState := cisHex2;
      cisHex2:
        CurState := cisHex3;
      cisHex3:
        CurState := cisHex4;
      cisHex4:
        Result := False; // Mehr als 4 hexadezimale Zeichen hintereinander geht nicht
    end;
  end;

  function CheckColon: Boolean;
  begin
    Result := True;
    case CurState of
      cisNone:
        CurState := cisColonStart;
      cisColon:
        if DoubleColon or (CurBlock > 7) then
          Result := False // zweimal :: geht nicht,
               // außerdem steht :: für mind. 1 Block, mehr als 8 geht nicht
        else
        begin
          CurState := cisDoubleColon;
          DoubleColon := True;
        end;
      cisColonStart:
        begin
          CurState := cisDoubleColon;
          DoubleColon := True;
        end;
      cisDoubleColon:
        Result := False; // drittes : hintereinander ist nicht erlaubt
      cisHex1, cisHex2, cisHex3, cisHex4:
        CurState := cisColon;
    end;
  end;

  // Überprüfung ob IPv4 Adresse eingebettet ist
  function CheckDot: Boolean;
  type
    TCheckIP4State = (cis4Colon, cis4DoubleColon, cis4Zero, cis4F1, cis4F2, cis4F3, cis4F4);
  var
    j, Start: Integer;
    IP4State: TCheckIP4State;
  begin
    Result := False;
    Start := i - 1;
    while (Start > 0) and (Value[Start] <> ':') do
      Dec(Start);
    if Start = 0 then
      Exit;
    IP4State := cis4Colon;
    for j := Start - 1 downto 1 do
      case Value[j] of
        'f', 'F':
          case IP4State of
            cis4Colon:
              IP4State := cis4F1;
            cis4Zero:
              Exit;
            cis4F1:
              IP4State := cis4F2;
            cis4F2:
              IP4State := cis4F3;
            cis4F3:
              IP4State := cis4F4;
            cis4F4:
              Exit;
          end;
        '0':
          case IP4State of
            cis4Colon, cis4DoubleColon, cis4Zero:
              IP4State := cis4Zero;
          else
            Exit;
          end;
        '1'..'9':
          Exit;
        ':':
          case IP4State of
            cis4Colon:
              IP4State := cis4DoubleColon;
            cis4DoubleColon:
              Exit;
          else
            IP4State := cis4Colon;
          end;
      else
        Exit; // ungültiges Zeichen für IPv4 Einbettung
      end;
    if IP4State in [cis4DoubleColon, cis4Zero] then
      Result := CheckIPv4(Start + 1);
  end;

begin
  Result := False;
  DoubleColon := False;
  CurState := cisNone;
  CurBlock := 0;
  for i := 1 to Length(Value) do
    case Value[i] of
      'a'..'f', '0'..'9', 'A'..'F':
        if not CheckHexChars then
          Exit;
      ':':
        if not CheckColon then
          Exit;
      '.': // Überprüfung ob IPv4 Adresse eingebettet ist
        begin
          if CurBlock <= 7 then
            Result := CheckDot;
          Exit;
        end;
    else
      Exit; // ungültiges Zeichen
    end;
  Result := (CurState <> cisColon) and ((CurBlock = 8) or DoubleColon);
end;


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

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