Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Delphi中的IP地址字符串例程?_String_Delphi_Delphi 7_Ip Address - Fatal编程技术网

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

String Delphi中的IP地址字符串例程?,string,delphi,delphi-7,ip-address,String,Delphi,Delphi 7,Ip Address,我正在寻找一种在Delphi中验证和操作IP地址的方法。它应该能够做的一些事情是 验证字符串是否为有效的IP地址 验证字符串是否为有效的子网掩码 验证IP地址是否在给定子网内 用于存储IP地址的某种类型(记录、字符串或其他类型) IP地址类型的基本转换,例如字节的字符串或数组[0..3] 使IP操作更容易的任何其他IP地址例程 最基本的原因是,我想先看看这些东西是否已经存在,然后再继续重新设计它们。我已经编写了您需要的所有函数,但我恐怕无法共享代码 但是,该库在synaip单元中包含相当多的

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

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

最基本的原因是,我想先看看这些东西是否已经存在,然后再继续重新设计它们。

我已经编写了您需要的所有函数,但我恐怕无法共享代码

但是,该库在synaip单元中包含相当多的函数。e、 g

function IsIP(const Value: string): Boolean;
function IsIP6(const Value: string): Boolean;
function IPToID(Host: string): Ansistring;
function StrToIp6(value: string): TIp6Bytes;
function Ip6ToStr(value: TIp6Bytes): string;
function StrToIp(value: string): integer;
function IpToStr(value: integer): string;
function ReverseIP(Value: AnsiString): AnsiString;
function ReverseIP6(Value: AnsiString): AnsiString;
几年前我尝试这些函数时,IPv6函数有点问题,特别是在处理压缩的IPv6地址时

如果你想自己动手,这里有几点建议:

  • 操纵IPv4地址相当简单,因为它们只包含 32位,可存储为标准整数类型。IPv6 地址更难,因为它们需要128位,并且没有本机类型 那么多比特
  • 在尝试操作IP地址之前,首先将其转换为 整数(仅限IPv4)当然,IPv6将需要不同的存储 方法)。为此,请使用“.”作为分隔符拆分IP地址。 检查每个值是否仅包含数字且介于0之间 然后使用这些值生成最终的整数
  • IP地址转换为整数后,您可以 随便你怎么操纵它。例如,给定一个IP地址和 可以找到IP地址所属的子网的子网掩码 e、 g.IPtoInt(IPAddress)和NOT(IPtoInt(SubnetMask))=的整数 子网。现在,您可以将一个整数IP地址合并为整数 子网以查看IP是否位于子网内
  • 最后,将整数IP地址转换回字符串
如果您有任何具体的问题,我也可以尝试回答。

我还曾经写过一篇文章,其中包括两种类型的IP地址的自定义变体类型。显示了其功能的几个示例。最初,它设计用于在某些滑块控件(1)上以比例显示各种类型的值。当时的需求是这样的,默认的现有库是不够的,但我同意这里的评论,您可能只需要使用Indy(10!)或类似的工具就可以得到帮助

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

  • 问题4: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;
    
    函数strotipv4(const S:String):TIPv4;
    变量
    SIP:字符串;
    开始:整数;
    I:T4;
    索引:整数;
    计数:整数;
    SGroup:String;
    G:整数;
    开始
    SIP:=S+';
    开始:=1;
    对于I:=高(T4)至低(T4)do
    开始
    索引:=PosEx('.',SIP,Start);
    如果索引=0,则
    IPv4ErrorFmt(sinvalidipV4s值);
    计数:=索引-开始+1;
    SGroup:=复制(SIP,Start,Count-1);
    如果TryStrToInt(SGroup,G)和(G>=Low(Word))和(G High(Word))或(G<0),则
    IPv6ErrorFmt(SInvalidIPv6Value,S);
    结果:组[I]:=G;
    Inc(开始、计数);
    结束;
    结束;
    程序压缩旋转;
    变量
    I:T8;
    A:单词数组;
    开始
    SIP:=S+':';
    开始:=1;
    I:=高(T8);
    启动时High(Word))或(G<0),则
    IPv6ErrorFmt(SInvalidIPv6Value,S);
    结果:组[I]:=G;
    Inc(开始、计数);
    十二月一日;
    结束;
    FillChar(Result.H,(I+1)*SizeOf(Word),0);
    如果ZeroPos<(长度-1),则
    开始
    设定长度(A,I+1);
    开始:=ZeroPos+2;
    重复
    索引:=PosEx(“:”,SIP,Start);
    如果索引>0,则
    开始
    计数:=索引-开始+1;
    SGroup:='$'+复制(SIP,Start,Count-1);
    如果不是TryStrToInt(SGroup,G)或(G>High(Word))或(G<0),则
    IPv6ErrorFmt(SInvalidIPv6Value,S);
    A[I]:=G;
    Inc(开始、计数);
    十二月一日;
    结束;
    直到指数=0;
    公司(一);
    计数:=长度(A)-I;
    移动(A[I],Result.H,Count*SizeOf(Word));
    结束;
    结束;
    程序点表示法;
    变量
    I:T4;
    开始
    如果大写(复制(S,ZeroPos+2,4))'FFFF',则
    IPv6ErrorFmt(SInvalidIPv6Value,S);
    FillChar(Result.E,5*SizeOf(Word),0);
    结果.F:=$FFFF;
    SIP:=S+';
    开始:=ZeroPos+7;
    对于I:=低(T4)至高(T4)do
    开始
    索引:=PosEx('.',SIP,Start);
    如果索引=0,则
    IPv6ErrorFmt(SInvalidIPv6Value,S);
    计数:=索引-开始+1;
    SGroup:=复制(SIP,Start,Count-1);
    如果不是TryStrToInt(SGroup,G)或(G>High(Byte))或(G<0),则
    IPv6ErrorFmt(SInvalidIPv6Value,S);
    案例一
    0:结果。G:=G shl 8;
    1:Inc(结果G,G);
    2:结果H:=G shl 8;
    3:Inc(结果H,G);
    结束;
    Inc(开始、计数);
    结束;
    结束;
    开始
    ZeroPos:=Pos(“::”,S);
    如果ZeroPos=0,则
    正规符号
    其他的
    开始
    DotPos:=位置('.',S);
    如果DotPos=0,则
    压缩旋转
    其他的
    点四元表示法;