谁能帮我把这个小PHP代码转换成Delphi?

时间:2012-01-06 17:14:09

标签: php delphi

大家好,

我在PHP中有一个小代码,我想在Delphi中转换,我有一些麻烦...
这是PHP代码:

$from = "121.198.0.0";
$to = "121.198.255.255";
$arry1 = explode(".", $from);
$arry2 = explode(".", $to);
$a1    = $arry1[0];
$b1    = $arry1[1];
$c1    = $arry1[2];
$d1    = $arry1[3];
$a2    = $arry2[0];
$b2    = $arry2[1];
$c2    = $arry2[2];
$d2    = $arry2[3];
while ($d2 >= $d1 || $c2 > $c1 || $b2 > $b1 || $a2 > $a1) {
    if ($d1 > 255) {
        $d1 = 1;
        $c1++;
    }
    if ($c1 > 255) {
        $c1 = 1;
        $b1++;
    }
    if ($b1 > 255) {
        $b1 = 1;
        $a1++;
    }
    echo "$a1.$b1.$c1.$d1<br>";
    $d1++;
}

在Delphi中我开始说:

procedure TForm1.Button1Click(Sender: TObject);
var
  Arry1, Arry2: TStringList;
  RangeFrom, RangeTo: string;
  a1, b1, c1, d1, a2, b2, c2, d2: string;
begin
  RangeFrom := Edit1.Text;
  RangeTo := Edit2.Text;
  Arry1 := Explode('.', RangeFrom);
  Arry2 := Explode('.', RangeTo);
  a1 := Arry1[0];
  b1 := Arry1[1];
  c1 := Arry1[2];
  d1 := Arry1[3];
  a2 := Arry1[0];
  b2 := Arry1[1];
  c2 := Arry1[2];
  d2 := Arry1[3];
  while (StrToInt(d2) >= StrToInt(d1))
    //and StrToInt(c2) > (StrToInt(c1)
    //and StrToInt(b2) > (StrToInt(b1)
    //and StrToInt(a2) > (StrToInt(a1)
  do
  begin
    if (StrToInt(d1) > 255) then
    begin
        d1 := '1';
        StrToInt(c1)+1;
    end;
    if (StrToInt(c1) > 255) then
    begin
        c1 := '1';
        StrToInt(b1)+1;
    end;
    if (StrToInt(b1) > 255) then
    begin
        b1 := '1';
        StrToInt(a1)+1;
    end;
    ListBox1.Items.Add(a1+'.'+b1+'.'+c1+'.'+d1);
    StrToInt(d1)+1;
  end;
end;

(对于爆炸功能,我使用:http://www.marcosdellantonio.net/2007/06/14/funcao-explode-do-php-em-delphi/

有人可以帮我在Delphi中编写这个小代码吗?

提前致谢:)

贝尼

3 个答案:

答案 0 :(得分:6)

通过查看代码,我可以看到以下内容:

如果您认为参数{_ 1}}的顺序错误。分隔符是您链接的函数中的第二个参数。所以你应该写:

Explode

您正在通过不释放Arry1 := Explode(RangeFrom, '.'); Arry2 := Explode(RangeTo, '.'); 函数返回的数组来泄漏内存。 Delphi与PHP的不同之处在于您经常需要管理您创建的对象的内存。


Explode

这些应该是a2 := Arry1[0]; b2 := Arry1[1]; c2 := Arry1[2]; d2 := Arry1[3]; 而不是Arry2


您应该先将字符串转换为整数。所以声明他们是这样的:

Arry1

并写下这样的作业:

a1, b1, c1, d1, a2, b2, c2, d2: Integer;

a1 := StrToInt(Arry1[0]);
b1 := StrToInt(Arry1[1]);
//etc. etc.

转换为:

while ($d2 >= $d1 || $c2 > $c1 || $b2 > $b1 || $a2 > $a1)

在while循环中你需要这样的代码:

while ((d2 >= d1) or (c2 > c1) or (b2 > b1) or (a2 > a1))

使用if d1 > 255 then begin d1 := 1; inc(c1); end; 函数将4个值转换回IP地址最简单:

Format

你误解了ListBox1.Items.Add(Format('%d.%d.%d.%d', [a1, b1, c1, d1])); 这是一个函数,它接收一个字符串作为输入并返回一个整数。当你写:

StrToInt

您没有修改变量StrToInt(d1)+1 ,它只是一个输入变量。当您进行我描述的其他更改时,该问题就会消失,但我想指出它以便您将来获益。


您可能还想强制定期重新绘制列表框,以便查看正在发生的事情。


把它们放在一起就可以了:

d1

答案 1 :(得分:0)

我认为它现在没有做任何事情的原因是你在edit1.text或edit2.text中可能没有任何值。

为了测试(在使这个片段成为一个过程或函数之前),您可以将一些测试数据分配给RangeFrom和RangeTo。

实施例。 RangeFrom:='121.198.0.0'; RangeTo:='121.198.255.255';

答案 2 :(得分:0)

测试目标:

procedure TForm1.Button1Click(Sender: TObject);
var
  AddrList: TStringList;
  StartAddress,
  EndAddress: Cardinal;
  a, b, c, d: PByte;
  x: Cardinal;
begin
  AddrList := TStringList.Create;
  AddrList.Delimiter := '.';
  AddrList.DelimitedText := Edit1.Text;
  StartAddress := (Cardinal(StrToInt(AddrList.Strings[0])) shl 24 ) +
                  (Cardinal(StrToInt(AddrList.Strings[1])) shl 16) +
                  (Cardinal(StrToInt(AddrList.Strings[2])) shl 8) +
                  StrToInt(AddrList.Strings[3]);

  AddrList.DelimitedText := Edit2.Text;
  EndAddress := (Cardinal(StrToInt(AddrList.Strings[0])) shl 24 ) +
                  (Cardinal(StrToInt(AddrList.Strings[1])) shl 16) +
                  (Cardinal(StrToInt(AddrList.Strings[2])) shl 8) +
                  StrToInt(AddrList.Strings[3]);
  AddrList.Free;

  for x := StartAddress to EndAddress do begin
    a := @x;
    b := a;
    Inc(a);
    c := a;
    Inc(a);
    d := a;
    Inc(a);
    Memo1.Lines.Add(Format('%d.%d.%d.%d', [a^,d^,c^,b^]));
  end;
end;