【问题标题】:Basic IP validation within Inno Setup scriptInno Setup 脚本中的基本 IP 验证
【发布时间】:2011-09-20 02:30:00
【问题描述】:

当我收集用户的输入时,我如何检查它是否是 IP 地址?

【问题讨论】:

    标签: windows ip-address inno-setup pascalscript


    【解决方案1】:

    IP 地址(假设您指的是 IPv4)实际上是一个整数,但它通常写成四个数字,由 . 分隔。这些数字中的每一个都代表整数的一个字节值,因此每个数字都应该是 0 到 255(包括)之间的数字。

    function CheckIP(Input: String): Cardinal;
    var
      IP: Cardinal;
      i : Integer;
      Part: Integer;
      PartValue: Cardinal;
      PartValid: Boolean;
    begin
      Part := 3;
      PartValue := 0;
      PartValid := False;
      IP := 0;
      { When a '.' is encountered, the previous part is processed. Force processing }
      { the last part by adding a '.' to the input. }
      Input := Input + '.';
    
      for i := 1 to Length(Input) do
      begin
    
        { Check next character }
        if Input[i] = '.' then
        begin
    
           if PartValue <= 255 then
           begin
             if PartValid then
             begin
               { A valid part is encountered. Put it in the result. }
               IP := IP or (PartValue shl (Part * 8));
               { Stop processing if this is the last '.' we put in ourselves. }
               if i = Length(Input) then
                 Break;
               { Else reset the temporary values. }
               PartValid := False;
               PartValue := 0;
               Dec(Part);
             end
             else
               RaiseException('Empty part');
           end
           else
             RaiseException('Part not within 0..255');
    
        end
        else if ((Input[i] >= '0') and (Input[i] <= '9')) then
        begin
    
          { A digit is found. Add it to the current part. }
          PartValue := PartValue * 10 + Cardinal((Ord(Input[i]) - Ord('0')));
          PartValid := True;
    
        end
        else
        begin
    
          { Any other character raises an exception }
          RaiseException('Invalid character');
    
        end;
    
        { If part < 0, we processed too many dots. }
        if Part < 0 then
          RaiseException('Too many dots');
    
      end;
    
      { Check if we found enough parts. }
      if Part > 0 then
        RaiseException('Address most consist of 4 numbers');
    
      { If Part is not valid after the loop, the input ended in a dot. }
      if not PartValid then
        RaiseException('IP cannot end in a dot');
    
      { Return the calculated IP address as a cardinal. }
      Result := IP;
    end;
    

    【讨论】:

    • 我知道这一点。我在用帕斯卡问怎么做,用于 inno 设置。
    • 我不知道这个 Inno 设置脚本,所以我在 Delphi 中编写了一个函数,并试图省略任何可能是特定 Delphi 的函数。该函数检查输入字符串并将 IP 地址作为基数返回。如果发现错误,该函数将引发异常。您可以使用结果进一步检查 IP 是否在特定范围内。如果此脚本不支持异常,您将不得不寻找另一种解决方案,例如让函数返回 True 或 False,并在 out 参数中返回 IP。
    • 对于 Delphi,此代码将极其复杂且效率低下(例如,无需逐个字符循环)。
    • @TLama 是的,对于 Delphi 来说是这样。幸运的是,这不是 Delphi 问题。 :)
    【解决方案2】:

    我修改了代码,现在你可以在 Inno 设置中使用它:

    //Validate an IPv4 address
    function ValidateIP(
      Input: String
      ): Boolean;
    var
      InputTemp : String;
      IP: Cardinal;
      i : Integer;
      Part: Integer;
      PartValue: Cardinal;
      PartValid: Boolean;
    begin
      InputTemp := Input;
      Result := True;
    
      Part := 3;
      PartValue := 0;
      PartValid := False;
      IP := 0;
      // When a '.' is encountered, the previous part is processed. Force processing
      // the last part by adding a '.' to the input.
      Input := Input + '.';
    
      for i := 1 to Length(Input) do
      begin
        // Check next character
        if Input[i] = '.' then
        begin
    
           if PartValue <= 255 then
           begin
             if PartValid then
             begin
               // A valid part is encountered. Put it in the result.
               IP := IP or (PartValue shl (Part * 8));
               // Stop processing if this is the last '.' we put in ourselves.
               if i = Length(Input) then
                 Break;
               // Else reset the temporary values.
               PartValid := False;
               PartValue := 0;
               Dec(Part);
             end
             else
               Result := False;
           end
           else
             Result := False;
    
        end
        else if ( (((Ord(Input[i]) - Ord('0'))) >= 0) and ((Ord(Input[i]) - Ord('0')) <= 9) ) then
        begin
          // A digit is found. Add it to the current part.
          PartValue := PartValue * 10 + Cardinal((Ord(Input[i]) - Ord('0')));
          PartValid := True;
        end
        else
        begin
          // Any other character 
         Result := False;
        end;
        // If part < 0, we processed too many dots.
        if Part < 0 then
          Result := False;
      end;
      // Check if we found enough parts.
      if Part > 0 then
        Result := False;
      // If Part is not valid after the loop, the input ended in a dot.
      if not PartValid then
        Result := False;
    end;
    

    【讨论】:

    • 伙计们,猜猜谁最清楚如何在 Windows 上将字符串转换为 IP 地址?是温索克。它可以转换那些疯狂的点或非点八进制,十六进制和混合符号。虽然RtlIpv4StringToAddress 功能会更好,但它已添加到Vista 中,因此我在linked code 中使用了inet_addr
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 2021-01-21
    • 2019-03-23
    • 1970-01-01
    • 2022-10-19
    相关资源
    最近更新 更多