gpt4 book ai didi

string - Delphi 中的 IP 地址字符串例程?

转载 作者:行者123 更新时间:2023-12-03 15:41:12 26 4
gpt4 key购买 nike

我正在 Delphi 中寻找一种方法来验证和操作 IP 地址。它应该能够做的一些事情是......

  • 验证字符串是否为有效的 IP 地址
  • 验证字符串是否是有效的子网掩码
  • 验证 IP 地址是否位于给定子网内
  • 用于存储 IP 地址的某种类型(记录或字符串或其他类型)
  • IP 地址类型的基本转换,例如 StringArray[0..3] of Byte
  • 任何其他可以使 IP 操作变得更容易的 IP 地址例程

基本原因是,在我继续重新发明它们之前,我想看看这些东西是否已经存在。

最佳答案

我也曾经写过IPv4 and IPv6 conversion unit包括针对这两种类型的 IP 地址的自定义变体类型。 This answer显示了其功能的一些示例。最初,它的设计目的是在某些 slider 控件 1) 上按比例可视化各种类型的值。当时的要求是默认的现有库是不够的,但我同意这里的评论,你可能会得到印地(10!)或类似的帮助。

用该单元中的一些代码片段回答您的问题列表:

  • Q4:IP 类型的存储类型:

      const
    IPv4BitSize = SizeOf(Byte) * 4 * 8;
    IPv6BitSize = SizeOf(Word) * 8 * 8;

    type
    T4 = 0..3;
    T8 = 0..7;
    TIPv4ByteArray = array[T4] of Byte;
    TIPv6WordArray = array[T8] of Word;

    TIPv4 = packed record
    case Integer of
    0: (D, C, B, A: Byte);
    1: (Groups: TIPv4ByteArray);
    2: (Value: Cardinal);
    end;

    TIPv6 = packed record
    case Integer of
    0: (H, G, F, E, D, C, B, A: Word);
    1: (Groups: TIPv6WordArray);
    end;
  • 问题 5:将 IP 地址字符串转换为这些记录或数组类型:

      function StrToIPv4(const S: String): TIPv4;
    var
    SIP: String;
    Start: Integer;
    I: T4;
    Index: Integer;
    Count: Integer;
    SGroup: String;
    G: Integer;
    begin
    SIP := S + '.';
    Start := 1;
    for I := High(T4) downto Low(T4) do
    begin
    Index := PosEx('.', SIP, Start);
    if Index = 0 then
    IPv4ErrorFmt(SInvalidIPv4Value, S);
    Count := Index - Start + 1;
    SGroup := Copy(SIP, Start, Count - 1);
    if TryStrToInt(SGroup, G) and (G >= Low(Word)) and (G <= High(Word)) then
    Result.Groups[I] := G
    else
    Result.Groups[I] := 0;
    Inc(Start, Count);
    end;
    end;

    function StrToIPv6(const S: String): TIPv6;
    { Valid examples for S:
    2001:0db8:85a3:0000:0000:8a2e:0370:7334
    2001:db8:85a3:0:0:8a2e:370:7334
    2001:db8:85a3::8a2e:370:7334
    ::8a2e:370:7334
    2001:db8:85a3::
    ::1
    ::
    ::ffff:c000:280
    ::ffff:192.0.2.128 }
    var
    ZeroPos: Integer;
    DotPos: Integer;
    SIP: String;
    Start: Integer;
    Index: Integer;
    Count: Integer;
    SGroup: String;
    G: Integer;

    procedure NormalNotation;
    var
    I: T8;
    begin
    SIP := S + ':';
    Start := 1;
    for I := High(T8) downto Low(T8) do
    begin
    Index := PosEx(':', SIP, Start);
    if Index = 0 then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    Count := Index - Start + 1;
    SGroup := '$' + Copy(SIP, Start, Count - 1);
    if not TryStrToInt(SGroup, G) or (G > High(Word)) or (G < 0) then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    Result.Groups[I] := G;
    Inc(Start, Count);
    end;
    end;

    procedure CompressedNotation;
    var
    I: T8;
    A: array of Word;
    begin
    SIP := S + ':';
    Start := 1;
    I := High(T8);
    while Start < ZeroPos do
    begin
    Index := PosEx(':', SIP, Start);
    if Index = 0 then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    Count := Index - Start + 1;
    SGroup := '$' + Copy(SIP, Start, Count - 1);
    if not TryStrToInt(SGroup, G) or (G > High(Word)) or (G < 0) then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    Result.Groups[I] := G;
    Inc(Start, Count);
    Dec(I);
    end;
    FillChar(Result.H, (I + 1) * SizeOf(Word), 0);
    if ZeroPos < (Length(S) - 1) then
    begin
    SetLength(A, I + 1);
    Start := ZeroPos + 2;
    repeat
    Index := PosEx(':', SIP, Start);
    if Index > 0 then
    begin
    Count := Index - Start + 1;
    SGroup := '$' + Copy(SIP, Start, Count - 1);
    if not TryStrToInt(SGroup, G) or (G > High(Word)) or (G < 0) then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    A[I] := G;
    Inc(Start, Count);
    Dec(I);
    end;
    until Index = 0;
    Inc(I);
    Count := Length(A) - I;
    Move(A[I], Result.H, Count * SizeOf(Word));
    end;
    end;

    procedure DottedQuadNotation;
    var
    I: T4;
    begin
    if UpperCase(Copy(S, ZeroPos + 2, 4)) <> 'FFFF' then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    FillChar(Result.E, 5 * SizeOf(Word), 0);
    Result.F := $FFFF;
    SIP := S + '.';
    Start := ZeroPos + 7;
    for I := Low(T4) to High(T4) do
    begin
    Index := PosEx('.', SIP, Start);
    if Index = 0 then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    Count := Index - Start + 1;
    SGroup := Copy(SIP, Start, Count - 1);
    if not TryStrToInt(SGroup, G) or (G > High(Byte)) or (G < 0) then
    IPv6ErrorFmt(SInvalidIPv6Value, S);
    case I of
    0: Result.G := G shl 8;
    1: Inc(Result.G, G);
    2: Result.H := G shl 8;
    3: Inc(Result.H, G);
    end;
    Inc(Start, Count);
    end;
    end;

    begin
    ZeroPos := Pos('::', S);
    if ZeroPos = 0 then
    NormalNotation
    else
    begin
    DotPos := Pos('.', S);
    if DotPos = 0 then
    CompressedNotation
    else
    DottedQuadNotation;
    end;
    end;

对于 Q1 到 Q3,您必须自己导出一些例程,但这应该没有任何问题。

1) 对于那些感兴趣的人,它是 this slider controlthis topic作为该单元的启动。

关于string - Delphi 中的 IP 地址字符串例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8525314/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com