Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
IPParser Uygulama Test Ricası
#1
Merhaba,

Windows Platformu için Delphi 10.3 kullanarak "Open Source Network IP Scanner" Geliştiriyorum. Bu bağlamda Girilen IP adreslerini parse edip içerdikleri geçerli IP adreslerini listeyelen bir Lib yazdım. Kodları test amaçlı çalıştıracak bir ufak uygulama yapıp hatalı mı yoksa düzgün mü çalışıyor diye test ediyorum.

Rica etsem gözümden kaçabilecek hatalı olabilecek durumları tespit için sizlerde test edebilirmisiniz. ?

Bir programın parçası olacağı için ilgili Lib unitini şuan paylaşmak yerine proje bitiminde github üzerinden komple paylaşmak istiyorum. Ama eğer içeriği illaki görmek isterseniz bu konuya kodları eklerim.

Test Uygulamasında 2 adet giriş var.

Ip adresleri,network vs girişi için yazım formatları aşağıdaki gibidir ve Eş değerleri sağ taraftakidir.

192.168.1.1-254       -->  (192.168.1.1..192.168.1.254)
192.168.1.1-2.254    -->  (192.168.1.1..192.168.2.254)
192.168.1.1-169.1.1 -->  (192.168.1.1..192.169.1.1)
192.168.1.1-193.168.1.1 --> (192.168.1.1..193.168.1.1)

4.4.4.4/21 --> (4.4.4.4/255.255.248.0) --> (4.4.0.1..4.4.7.254)

8.8.8.8/255.255.255.0 --> (8.8.8.1..8.8.8.254)

172.16.77.1  --> (172.16.77.1)

7.7.7.0/24 --> (7.7.7.1..7.7.7.254)

Birden Fazla yazmayı destekler sadece aralara "," virgül koymak  yeterlidir. Boşluk Etkisiz Kabul edilir.

Ör : 172.16.77.1-150, 8.8.8.8, 192.168.1.1/24

İlgili Oktetler Duruma göre min 0 veya 1 olabilir ama Max 254 olabilir.

Ör : 172.16.1.255  --> Geçersiz IP kabul edilir. Çünkü Host IP adresi değildir. Broadcast IP adresidir. Networkte kullanılmaz.
       172.16.1.0     -->  Geçersiz IP kabul edilir. Çünkü Host IP adresi değildir. Networkü komple temsil eder. Networkte kullanılmaz.
    
       172.16.300.1 --> Geçersizdir. 1 oktet en fazla 254 olabilir. 300 olamaz.

Kullanılan Noktalamalar.

, (virgül) -> Farklı Aralıkları yanyana yazmak için kullanılan ayraçtır.
. (nokta) -> IP adresindeki Oktetleri birbirinden ayırmak için kullanılır.
/ (Eğik Çizgi) -> Mask adresini vermek için IP ile Mask arasına konur.
- (tire) -> Bir subnetteki IP aralığını belirler. 192.168.1.1-254 gibi.

Noktalamalar yan yana gelemez. Başta ve sonra noktalama olamaz.

IZINLI_KARAKTERLER  = '1234567890,-./'  Bunun dışındaki hiçbir karakteri kabul etmez. Geçersiz Sayar.

2. giriş ise sayısal olarak yapılan giriştir. Bir IP aralığındaki max IP adresini ifade eder. Bunu ekleme nedenim özellikle uzun ve yanlış yazılan bir aralık olursa hesaplaması çok zaman almaktadır. mesela 192.168.1.1/20 yazılırsa toplamda 4096 IP adresi hesaplanır. Ama biz bunu 3072 ile sınırlandırırsak program hesaplamaz ve hata kodu döndürür.

Bu bilgiler eşliğinde Test yapıp benim gözden kaçırdığım durumları tespit etmeniz mümkün müdür ?


.zip   IPParser.zip (Dosya Boyutu: 658,64 KB / İndirme Sayısı: 5)
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.

Sadece Hobiciyim..
WWW
Cevapla
#2
Emeğine sağlık. Bence çok yararlı olacaktır.

Bilmiyorum sorun teşkil eder mi ama:
192.168.001.001-2
şeklinde giriş yaptığımda güzel bir şekilde 2 IP'yi veriyor;
192.168.1.1
192.168.1.2

Ama sadece 192.168.001.001 yazdığımda 192.168.1.1 değil de 192.168.001.001 şeklinde sonuç dönüyor. Çıktının standart olması açısından son çıktının 192.168.1.1 olmasını beklerdim.
There's no place like 127.0.0.1
WWW
Cevapla
#3
(14-05-2019, Saat: 12:24)SimaWB Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Emeğine sağlık. Bence çok yararlı olacaktır.

Bilmiyorum sorun teşkil eder mi ama:
192.168.001.001-2
şeklinde giriş yaptığımda güzel bir şekilde 2 IP'yi veriyor;
192.168.1.1
192.168.1.2

Ama sadece 192.168.001.001 yazdığımda 192.168.1.1 değil de 192.168.001.001 şeklinde sonuç dönüyor. Çıktının standart olması açısından son çıktının 192.168.1.1 olmasını beklerdim.

Hocam teşekkürler. Bu tür eksikleri bulmak adına konuyu açtım. Dediğiniz güncellemeyi yapacağım. farklı bakış açılarına ihtiyacım var. gözünüze çarpan birşey olursa mutlaka yazın.
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.

Sadece Hobiciyim..
WWW
Cevapla
#4
@SimaWB  Gerekli Düzenlemeyi Yaptım. Başka sorun bulan Arkadaşlar olursa mutlaka yazsınlar ki düzenleyeyim. Teşekkürler.


.zip   IPParser.zip (Dosya Boyutu: 658,64 KB / İndirme Sayısı: 7)

Kodlar

unit IPv4Parser;
////////////////////////////////////////////////////////////////////////////////
///
///    IPParser @2019.05
///    Programmer : Sercan TEK - Turkey - Tekirdağ
///    IDE  : Embarcadero® Delphi 10.3 Version 26.0.33219.4899
///
///    IPv4 Parse ve Aralık Hesaplama Alt Programlarını içerir.
///
///    Giriş Örneği : String : 192.168.1.1-254,172.16.59.1/24,8.8.8.8
///    Çıkış        : StringList
///
///    http://www.sercanca.com
///
////////////////////////////////////////////////////////////////////////////////

interface

uses
 System.SysUtils,
 VCL.Dialogs,
 Windows,
 System.Classes;

//IPListesini Oluşturur.
Function IPListCreate(IpString: String;const List: TStrings;
                     Max_IP_Count:integer=1024): boolean;

// Verilen String İfadenin Karakter Analizini yapar.
function StringControl(Giris: string): boolean;

// IPv4 Adresinin geçerliliğini Kontrol Eder.
function IPv4Check(IP: string;Tur:byte): boolean;

var
// Eğer Hata olursa Geriye False Döner ve Error Değişkenine Hata mesajı Gelir.
Error   : string;
_Time   : DWord;

Calculate_Second : Double;
Ipv4Count : integer;

// Hesaplanacak Aralığın max boyutu
Max_Range : integer;

const
_Error_GecersizIP           = '( %s ) : IPv4 Adresi Geçersiz';
_Error_Basla_Biti_Karakter  = 'Başlangıç - Bitiş Karakteri Noktalama Olamaz.';
_Error_Yabanci_karakter     = '( %s ) : Geçersiz Karakter';
_Error_Hatali_Noktalama     = '(..  %s  ..) : Noktalama Hatası';
_Error_Bos_Data             = ' Lütfen Ipv4 Adres Girişi Yapın.';
_Error_Bitis_Baslangic_Hata = '( %s-%s ) Ipv4 Aralık Hatalı';
_Error_GecersizMask         = '( %s ) : Mask Adresi Geçersiz';
_Error_GecersizNetwork      = '( %s ) : Geçersiz Network Adresi';
_Error_GecersizSubnet       = '( %s ) : Geçersiz Subnet ve Mask Adresi';
_Error_Max_Range            = '( %s .. %s : %s ) Belirlenen Aralık Aşıldı.( Max : %s )';

const
IP_NETMASK   = 1;
IP_HOST      = 2;
IP_NETWORK   = 3;
IPV4_MAX_BIT = 32;

MIN = 1 ;
MAX = 2 ;

ARALIK_AYRAC = '-';
GRUP_AYRAC   = ',';
SUBNET_AYRAC = '/';
OKTET_AYRAC  = '.';

IZINLI_KARAKTERLER  = '1234567890,-./';
IZINLI_NOKTALAMALAR = ',-./';

// Ipv4 tipinde Yapı Tanımlanıyor.
type
 IPv4 = record
   Octet: array [1 .. 4] of byte;
   function ToString: string;
   function Toint: integer;
 end;

implementation

function IPv4.ToString: string;
// Ipv4 Türünü String olarak Yazdırır.
begin
Result := Octet[1].ToString + OKTET_AYRAC+
          Octet[2].ToString + OKTET_AYRAC+
          Octet[3].ToString + OKTET_AYRAC+
          Octet[4].ToString;
end;

function IPv4.Toint: integer;
// Tanımlanan IPv4 formatını Cardinal geri çevirir.
begin
 Result := (Octet[1] * 16777216) + (Octet[2] * 65536) +
   (Octet[3] * 256) + (Octet[4]);
end;

procedure Ipv4ListAdd(IP:String;const List: TStrings);
// Listede aynı IP Adresleri varsa eklemesin.
begin
 if Ip.Trim<>'' then
   if List.IndexOf(IP.Trim)=-1 then
     List.Add(IP.Trim);
end;

function ErrorMessage(hata:String):Boolean;
// Hata Mesajını "Error" Değişkenine Yükler ve Geriye "False" Döner.
begin
 Result := False;
 Error := Hata;
end;

function IPv4Check(IP: string;Tur:byte): boolean;
// String Formatındaki IP adresini istenilen Formata göre Kontrol Eder.
// Geçerli ise True
// Geçersiz ise False
var
 i, j, l: byte;
 ips: array [1 .. 4] of string;
begin
 Result := True;
 i := 1;

 for l := 1 to 4 do
   ips[l] := '';

 for j := 1 to length(ip) do
   if ip[j] <> OKTET_AYRAC then
   begin
     if (ip[j] < '0') or (ip[j] > '9') then
     begin
       Result := ErrorMessage(Format(_Error_GecersizIP,[IP]));
       exit;
     end;
     ips[i] := ips[i] + ip[j];
   end
   else
     Inc(i);

 case Tur of
  IP_HOST : begin
              if (i <> 4) or // 4 Oktet Olmak Zorunda !!
               // 1. Oktet : 1..254
                  ((ips[1].ToInteger > 254) or   (ips[1].ToInteger < 1)) or
               // 2. Oktet : 0..254
                  ((ips[2].ToInteger > 254) or   (ips[2].ToInteger < 0)) or
               // 3. Oktet : 0..254
                  ((ips[3].ToInteger > 254) or (ips[3].ToInteger < 0)) or
              // 4. Oktet : 1..254
                  ((ips[4].ToInteger > 254) or   (ips[4].ToInteger < 1)) then
                   Result := ErrorMessage(Format(_Error_GecersizIP,[IP]));
            end;

  IP_NETMASK : begin
              if (i <> 4) or // 4 Oktet Olmak Zorunda !!
                  // 1. Oktet : 1..255
                 ((ips[1].ToInteger > 255) or   (ips[1].ToInteger < 0)) or
                 // 2. Oktet : 0..255
                 ((ips[2].ToInteger > 255) or   (ips[2].ToInteger < 0)) or
                 // 3. Oktet : 0..255
                 ((ips[3].ToInteger > 255) or (ips[3].ToInteger < 0)) or
                // 4. Oktet : 1..255
                 ((ips[4].ToInteger > 255) or   (ips[4].ToInteger < 0)) then
                Result := ErrorMessage(Format(_Error_GecersizMask,[IP]));
            end;

  IP_NETWORK: begin
              if (i <> 4) or // 4 Oktet Olmak Zorunda !!
               // 1. Oktet : 1..254
                  ((ips[1].ToInteger > 254) or   (ips[1].ToInteger < 1)) or
               // 2. Oktet : 0..254
                  ((ips[2].ToInteger > 254) or   (ips[2].ToInteger < 0)) or
               // 3. Oktet : 0..254
                  ((ips[3].ToInteger > 254) or (ips[3].ToInteger < 0)) or
               // 4. Oktet : 0..254
                  ((ips[4].ToInteger > 254) or   (ips[4].ToInteger < 0)) then
                Result := ErrorMessage(Format(_Error_GecersizNetwork,[IP]));
            end;
 end;

end;

function CharCount(Kelime: String;const Karakter: Char): byte;
// Girilen Karakterden kaç adet var olduğunu bulup sayısını geri döndürür.
var
 harf: int16;
 Bulunan: byte;
begin
 Bulunan := 0;
 for harf := 0 to length(Kelime) do
   if Kelime[harf] = Karakter then
     inc(Bulunan);
 Result := Bulunan;
end;

function StringControl(Giris: string): boolean;
// Girilen IP Bilgilerini Kontrol Eder.
// Eğer Hatalı Durum varsa Geriye False Döndürür.
var
 harf: int16;
Begin
 Result := True;

 if Giris.length > 0 then
 begin
   // ilk ve son karakter Noktalama Olamaz
   if (Pos(Giris[1], IZINLI_NOKTALAMALAR) > 0) or
      (Pos(Giris[length(Giris)],IZINLI_NOKTALAMALAR) > 0) then
     begin
      Result := ErrorMessage(_Error_Basla_Biti_Karakter);
      exit;
     end;

   // Karakter Kontrolü Yapılıyor.
   for harf := 1 to length(Giris) do
   begin
     // İzin Verilen Karakterlerin Kontrolü Yapılıyor.
     if Pos(Giris[harf], IZINLI_KARAKTERLER) <= 0 then
     begin
       Result := ErrorMessage(Format(_Error_Yabanci_karakter,[Giris[harf]]));
       exit;
     end;

     // Noktalamalar yanyana gelmesin.
     if  Pos(Giris[harf], IZINLI_NOKTALAMALAR) > 0 then
       if (Pos(Giris[harf - 1], IZINLI_NOKTALAMALAR) > 0) or
          (Pos(Giris[harf + 1],IZINLI_NOKTALAMALAR) > 0) then
             begin
              Result := ErrorMessage(Format(_Error_Hatali_Noktalama,
                            [(Giris[harf-1] + Giris[harf] + Giris[harf+1])]));
              exit;
             end;
   end;
 end
 else
   Result := ErrorMessage(_Error_Bos_Data);
End;

procedure StringSplit(const ayrac: Char;Giris: string; const List: TStrings);
// Verilen Stringi Verilen Ayraca göre Ayrıştırıp verilen TStrings Listesine Atar.
var
 AyracPos: byte;
 AyracAdet: byte;
 AyracSira: byte;
 ilkString: String;
 TempString: String;
begin
 TempString := Giris.Trim;
 AyracAdet := CharCount(TempString, ayrac);

 // Ayraç sayısına göre Hepsini Listeye Aktar.
 for AyracSira := 1 to AyracAdet do
 begin
   AyracPos := Pos(ayrac, TempString);
   ilkString := Copy(TempString, 0,AyracPos - 1);
   Delete(TempString, 1, AyracPos);
   List.Add(ilkstring);
 end;

 // Geride Kalan Varsa onuda Liste Aktar.
 if length(TempString) > 0 then
   List.Add(Copy(TempString, 0,length(TempString)));

end;

function IPGroupListSplit(Giris: string;const List: TStrings): byte;
// Birden Fazla IP Grubu Girildi ise Ayrıştırma işlemini Yapar ve
// Verilen TString Listesine Atar.
begin
 try
   StringSplit(GRUP_AYRAC, Giris, List);
 finally
   Result := List.Count;
 end;
end;

function intToIpv4(ip: integer): Ipv4;
// İnteger tipinde verilen IP adresini
// Ipv4 Tipinde geri döndürür.
var
 dizi: array [1 .. 4] of byte absolute ip;
begin
 Result.Octet[1] := dizi[4];
 Result.Octet[2] := dizi[3];
 Result.Octet[3] := dizi[2];
 Result.Octet[4] := dizi[1];
end;

function StrIpv4toIpv4(const IPstr: string;var IP:IPv4;
                       Tur:byte=IP_HOST): boolean;
// String tipindeki IP adresini Oktetlere Ayrırır.
// Hata Olursa False olmaz ise True Değerini Döndürür.
var
 n, x: byte;
 Posi: array [1 .. 4] of byte;
 Oktet: array [1 .. 4] of string;
begin
 Result := False;
 if IPv4Check(IPstr,Tur) then
 begin
   x := 0;
   for n := 1 to length(IPstr) do
   begin
     if IPstr[n] = OKTET_AYRAC then
     begin
       Inc(x);
       Posi[x] := n;
     end
     else
       Oktet[x + 1] := Oktet[x + 1] + IPstr[n];
   end;
   IP.Octet[1] := Oktet[1].ToInteger;
   IP.Octet[2] := Oktet[2].ToInteger;
   IP.Octet[3] := Oktet[3].ToInteger;
   IP.Octet[4] := Oktet[4].ToInteger;
   Result := True;
 end;
end;

procedure IPv4RangeCalculate(Baslagic, Bitis: integer;const List: TStrings);
// İnteger Tipinde verilen 2 IP arasındaki Tüm IP adreslerini Hesaplar
// Sonuçları Verilen TStrings Listesine Ekler.
var
 Siradaki: integer;
begin
 for Siradaki := Baslagic to Bitis do
 begin
 if IPv4Check(intToIpv4(Siradaki).ToString,IP_HOST) then
     Ipv4ListAdd(intToIpv4(Siradaki).ToString,List);
 end;
end;

function Ipv4RangeCount(Baslangic, Bitis: integer): integer;
// İnteger Tipinde verilen 2 IP arasında Kaç IP var Sayar
var
 Siradaki: integer;
 IPAdet : integer;
 Aralik : integer;
begin
 IPAdet := 0;

 Aralik := (Bitis-Baslangic)+1;

if Aralik > Max_Range then
 begin
  Result := Aralik ;
  Exit;
 end;

 for Siradaki := Baslangic to Bitis do
 begin
  if IPv4Check(intToIpv4(Siradaki).ToString,IP_HOST) then
     inc(IPAdet);
 end;
 result := IPAdet;
end;

function IPv4RangeFind(BaslaIP,BitisIP: string; const List: TStrings): boolean;
// String Tipinde verilen 2 IP arasındaki Tüm IP adreslerini Oluşturur.
// Oluşturduğu IP Adreslerini Hesaplama Fonksiyonuna gönderir.
// Sonuçları Verilen TStrings Listesine Ekler.
// Hata var ise False yok ise True Değerini Döndürür.
var
 BitisOkt:  IPv4;
 BaslaOkt : Ipv4;
 Tempint :  array[1..4] of int16;
 _BitisIP : String;
 IP_Aralik : integer;
begin

 Result := True;

 _BitisIP := BitisIP;

 // Baslangıç IP adresini hesaplama için BitişIP adresindeki Oktetlere ayırır.
   if not StrIpv4toIpv4(BaslaIP, BitisOkt ,IP_HOST) then
   Result := false;

   if not StrIpv4toIpv4(BaslaIP, BaslaOkt ,IP_HOST) then
   Result := false;

   if not result then exit;

   Tempint[1] := BitisOkt.Octet[1];
   Tempint[2] := BitisOkt.Octet[2];
   Tempint[3] := BitisOkt.Octet[3];
   Tempint[4] := BitisOkt.Octet[4];

 // Bitiş IP adresine göre Parse İşlemlerini Yapar.
  case CharCount(BitisIP, OKTET_AYRAC) of
   0: // 1 Oktet girildi ise,
     begin
       // 4.Okt Aktarılıyor.
       Tempint[4] := BitisIP.ToInteger;

       BitisOkt.Octet[4] := Byte(Tempint[4]);

     end;
   1: // 2 Oktet girildi ise,
     begin

      // 3.Okt Aktarılıyor.
      Tempint[3] := strtoint(Copy(BitisIP, 0,Pos(OKTET_AYRAC, BitisIP) - 1));
      // 4.Okt Aktarılıyor.
      Delete(BitisIP,1,Pos(OKTET_AYRAC, BitisIP));
      Tempint[4] := strtoint(Copy(BitisIP, 0,length(BitisIP)));

       BitisOkt.Octet[3] := byte(Tempint[3]);
       BitisOkt.Octet[4] := byte(Tempint[4]);

     end;
   2: // 3 Oktet Girildi ise
     begin

       // 2.Okt Aktarılıyor.
       Tempint[2] := strtoint(Copy(BitisIP, 0, Pos(OKTET_AYRAC, BitisIP) - 1));
       // 3.Okt Aktarılıyor.
       Delete(BitisIP,1,Pos(OKTET_AYRAC, BitisIP));
       Tempint[3] := strtoint(Copy(BitisIP, 0, Pos(OKTET_AYRAC, BitisIP) - 1));
       // 4.Okt Aktarılıyor.
       Delete(BitisIP,1,Pos(OKTET_AYRAC, BitisIP));
       Tempint[4] := strtoint(Copy(BitisIP, 0,length(BitisIP)));

       BitisOkt.Octet[2] := byte(Tempint[2]);
       BitisOkt.Octet[3] := byte(Tempint[3]);
       BitisOkt.Octet[4] := byte(Tempint[4]);

     end;
   3: // 4 Oktet girildi ise,
     begin

       // 1.Okt Aktarılıyor.
       Tempint[1] := strtoint(Copy(BitisIP, 0, Pos(OKTET_AYRAC, BitisIP) - 1));
       // 2.Okt Aktarılıyor.
       Delete(BitisIP,1,Pos(OKTET_AYRAC, BitisIP));
       Tempint[2] := strtoint(Copy(BitisIP, 0, Pos(OKTET_AYRAC, BitisIP) - 1));
       // 3.Okt Aktarılıyor.
       Delete(BitisIP,1,Pos(OKTET_AYRAC, BitisIP));
       Tempint[3] := strtoint(Copy(BitisIP, 0, Pos(OKTET_AYRAC, BitisIP) - 1));
       // 4.Okt Aktarılıyor.
       Delete(BitisIP,1,Pos(OKTET_AYRAC, BitisIP));
       Tempint[4] := strtoint(Copy(BitisIP, 0,length(BitisIP)));

       BitisOkt.Octet[1] := byte(Tempint[1]);
       BitisOkt.Octet[2] := byte(Tempint[2]);
       BitisOkt.Octet[3] := byte(Tempint[3]);
       BitisOkt.Octet[4] := byte(Tempint[4]);

     end
  end;

if ((Tempint[4] > 254) or  (Tempint[3] > 254) or (Tempint[2] > 254)) or
   ((Tempint[1] > 254) or  (Tempint[1] <= 0))then
 begin
  Result:=ErrorMessage(Format(_Error_Bitis_Baslangic_Hata,
                              [BaslaIP,_BitisIP]));
  Exit;
 end;

 if not Ipv4Check(BitisOkt.ToString,IP_HOST) then
 begin
    Result := ErrorMessage(Format(_Error_GecersizIP,
                                  [BitisOkt.ToString]));
    exit;
 end;

 if (BitisOkt.Toint < BaslaOkt.Toint) then
  Result := ErrorMessage(Format(_Error_Bitis_Baslangic_Hata,
                                [BaslaIP,_BitisIP]));


 // Başlangıç ve Bitiş IP aralığındaki Geçerli Host IP Sayısı
 IP_Aralik := Ipv4RangeCount(BaslaOkt.Toint,BitisOkt.Toint);

 if IP_Aralik > Max_Range then
    Result := ErrorMessage(Format(_Error_Max_Range,[BaslaIP,_BitisIP,
                                   IP_Aralik.ToString,Max_Range.ToString]));

 if Result then
   IPv4RangeCalculate(BaslaOkt.Toint, BitisOkt.Toint, List);

end;

function intCheck(strDeger:String;var sayi:byte):boolean;
// String Değer int türüne çevrilir mi kontrol eder.
// Çevrilirse intDeger Değişkenine Aktarır.ve Geriye True Döner.
begin
Result := true;
  try
    sayi := strDeger.ToInteger;
  except
    Result := false;
  end;
end;

function MasktoIPv4(Maskint:Byte):String;
// Sayı Formatında Verilen Mask Değerini IP formatına dönüştürür.
// 4.4.4.4/24 Girerse 4.4.4.4/255.255.255.0 Olarak Dönüştürür.
function BinToDec(Str: string): Integer;
function Pow(i, k: Integer): Integer;
var
 j, Count: Integer;
begin
 if k>0 then j:=2
   else j:=1;
    for Count:=1 to k-1 do
      j:=j*2;
  Result:=j;
end;
var
Len, Res, i: Integer;
Error: Boolean;
begin
 Error:=False;
 Len:=Length(Str);
 Res:=0;
  for i:=1 to Len do
   if (Str[i]='0')or(Str[i]='1') then
      Res:=Res+Pow(2, Len-i)*StrToInt(Str[i])
   else
    begin
      Error:=True;
      Break;
    end;
if Error=True then Result:=0
   else Result:=Res;
end;
var
MaskBit : String;
BitSayi : byte;
begin
Maskbit := '00000000000000000000000000000000';
for BitSayi := 1 to Maskint do
   Maskbit[BitSayi]:='1';

   Result := BinToDec(Copy(Maskbit,1,8)).toString  + OKTET_AYRAC +
             BinToDec(Copy(Maskbit,9,8)).toString  + OKTET_AYRAC +
             BinToDec(Copy(Maskbit,17,8)).toString + OKTET_AYRAC +
             BinToDec(Copy(Maskbit,25,8)).toString;
end;

function IPv4MaskCalculate(Subnet,Mask:String;const List: TStrings):Boolean;
var
IpAralik : integer;

B_SubnetMask   : Ipv4 ;
B_AddressIP    : Ipv4 ;
B_NetworkIP    : Ipv4 ;
B_HostMinIP    : Ipv4 ;
B_HostMaxIP    : Ipv4 ;
B_WildcardIP   : Ipv4 ;
B_BroadcastIP  : Ipv4 ;

begin

Result := True;

StrIpv4toIpv4(Subnet,B_AddressIP,IP_NETWORK);
StrIpv4toIpv4(Mask,B_SubnetMask,IP_NETMASK);

// Wildcard Hesaplanıyor.
// Wildcard = (!SubnetMask)
  B_wildcardIP.Octet[1] := (not Byte(B_SubnetMask.Octet[1]));
  B_wildcardIP.Octet[2] := (not Byte(B_SubnetMask.Octet[2]));
  B_wildcardIP.Octet[3] := (not Byte(B_SubnetMask.Octet[3]));
  B_wildcardIP.Octet[4] := (not Byte(B_SubnetMask.Octet[4]));

// Network Hesaplanıyor.
// Network = (SubnetMask and AdresIP)
 B_NetworkIP.Octet[1] := B_SubnetMask.Octet[1] and B_AddressIP.Octet[1];
 B_NetworkIP.Octet[2] := B_SubnetMask.Octet[2] and B_AddressIP.Octet[2];
 B_NetworkIP.Octet[3] := B_SubnetMask.Octet[3] and B_AddressIP.Octet[3];
 B_NetworkIP.Octet[4] := B_SubnetMask.Octet[4] and B_AddressIP.Octet[4];

// Broadcast Ip Adresi Hesaplanıyor.
// Broadcast = (NetworkIP or Wildcard)
  B_BroadcastIP.Octet[1] := B_NetworkIP.Octet[1] or B_wildcardIP.Octet[1];
  B_BroadcastIP.Octet[2] := B_NetworkIP.Octet[2] or B_wildcardIP.Octet[2];
  B_BroadcastIP.Octet[3] := B_NetworkIP.Octet[3] or B_wildcardIP.Octet[3];
  B_BroadcastIP.Octet[4] := B_NetworkIP.Octet[4] or B_wildcardIP.Octet[4];

// Başlangıç IP adresi Hesaplanıyor.
// HostMinIP = (NetworkIP + 1)
  B_HostMinIP.Octet[1] :=  B_NetworkIP.Octet[1];
  B_HostMinIP.Octet[2] :=  B_NetworkIP.Octet[2];
  B_HostMinIP.Octet[3] :=  B_NetworkIP.Octet[3];
  B_HostMinIP.Octet[4] :=  B_NetworkIP.Octet[4]+1;

// Bitiş IP Adresi Hesaplanıyor.
// HostMaxIP = (Broadcast - 1)
  B_HostMaxIP.Octet[1]:= B_BroadcastIP.Octet[1];
  B_HostMaxIP.Octet[2]:= B_BroadcastIP.Octet[2];
  B_HostMaxIP.Octet[3]:= B_BroadcastIP.Octet[3];
  B_HostMaxIP.Octet[4]:= B_BroadcastIP.Octet[4]-1;

// Mask /31 veya /32 verilirse Başlangıç Ip adresi geri dönsün.
if (B_SubnetMask.Octet[4] = 254) or (B_SubnetMask.Octet[4] = 255)  then
  begin
     Ipv4ListAdd(B_AddressIP.ToString,List);
     exit;
  end;

 // Bitiş IP Adresi Başlangıç IP Adresinden Büyük Olamaz.
 if B_HostMaxIP.Toint < B_HostMinIP.Toint then
 begin
   Result := ErrorMessage(Format(_Error_Bitis_Baslangic_Hata,
              [B_HostMinIP.ToString,B_HostMaxIP.ToString]));
               //  showmessage('Hata');
 end;

 // Başlangıç ve Bitiş IP aralığındaki Geçerli Host IP Sayısı
 IPAralik := Ipv4RangeCount(B_HostMinIP.Toint,B_HostMaxIP.Toint);

 if IPAralik > Max_Range then
    Result := ErrorMessage(Format(_Error_Max_Range,
               [B_HostMinIP.ToString,B_HostMaxIP.ToString,
                 IPAralik.ToString,Max_Range.ToString]));

 if Result then
   IPv4RangeCalculate(B_HostMinIP.Toint,B_HostMaxIP.Toint, List);

end;

function IPv4SubnetMaskCalculate(Giris:String;const List: TStrings):Boolean;
// Network/Mask ya da Host/Mask şeklinde verilirse Aralığı Hesaplar.
var
Maskint : byte;
MaskStr : String;
Subnet  : String;

begin
Result := True;

if CharCount(Giris, SUBNET_AYRAC) <> 1 then
begin
   Result := ErrorMessage(Format(_Error_GecersizSubnet,[Giris]));
   exit;
end;

Subnet  := Trim(Copy(Giris,1,Pos(SUBNET_AYRAC,Giris)-1));
MaskStr := Trim(Copy(Giris,Pos(SUBNET_AYRAC,Giris)+1,Length(Giris)));

// Network/Subnet/Host Adresinin Doğruluğu Kontrol ediliyor.
if not IPv4Check(Subnet,IP_NETWORK) then
  if not IPv4Check(Subnet,IP_HOST) then
  begin
    Result := False;
    Exit;
  end;

// Sayı olarak girildi ise Onu IP Formatına çevirir.
if intCheck(MaskStr,Maskint) then
begin
  MaskStr := MasktoIPv4(Maskint);
 // Showmessage(MaskStr);
if Maskint > IPV4_MAX_BIT then // max 32 bit olabilir.
  begin
    Result := ErrorMessage(Format(_Error_GecersizMask,[Giris]));
    Exit;
  end;
end
else
// Eğer IP Formatında Girildi ise kontrol eder.
 begin
  if not IPv4Check(MaskStr,IP_NETMASK) then
    begin
      Result := False;
      Exit;
    end;
 end;

 Result := IPv4MaskCalculate(Subnet,MaskStr,List);

end;

function IPv4Formating(Giris:String):String;
// IP adresinde 192.168.001.001 girişi varsa
// 192.168.1.1 olarak formatlar.
var
IP : IPv4;
begin
 if StrIPv4toIPv4(Giris,IP,IP_HOST) then
   Result := IP.ToString;
end;

function IPv4Detect(Giris: string;const List: TStrings): boolean;
// Verilen Giris Bilgilerini Parse ederek Ayrıştırmaya gönderir.
// Sorun var ise False yoksa True Değerini Döner.
var
 BaslaIP: String;
 BitisIP: String;
begin

 Result := True;
 // Bir aralık ise İşle
 if CharCount(Giris, ARALIK_AYRAC) = 1 then
 begin

   BaslaIP := Copy(Giris, 0,Pos(ARALIK_AYRAC, Giris) - 1);

   // Başlangıç IP adresi Kontrol Ediliyor.
   if not IPv4Check(BaslaIP,IP_HOST) then
   begin
     Result := False;
     exit;
   end;

   BitisIP := Copy(Giris, Pos(ARALIK_AYRAC, Giris)+1, length(Giris));

   // Bitiş IP Adresi kontrol Ediliyor. Doğru ise Liste Oluşturulacak.
   if not IPv4RangeFind(BaslaIP, BitisIP,List) then
   begin
     Result := False;
     exit
   end;

 end
 else
 // Subnet Mask Girildi ise
 if CharCount(Giris, SUBNET_AYRAC) = 1 then
 begin
   if not IPv4SubnetMaskCalculate(Giris,List) then
   begin
     Result := False;
     exit
   end;
 end
 else
 // Eğer Aralık Değil ise işle
 begin
   if IPv4Check(Giris,IP_HOST) then
     Ipv4ListAdd(IPv4Formating(Giris),List)
   else
     Result := False;
 end;
end;

Function IPListCreate(IpString: String;const List: TStrings;
                     Max_IP_count:integer=1024): boolean;
// Verilen Giriş Bilgilerini işleyerek IPListesi Oluşturur.
// Hata oluşursa geriye False oluşmaz ise True Değeri Döner.
var
 IPGruplari: TStringList;
 IPGrupSatir: integer;
 satir: Integer;

begin
 result := true;
 _Time   := GetTickCount;

    // Boşluk varsa Temizler.
   if Pos(' ',IpString) > 0 then
      IpString :=  StringReplace(IpString, ' ', '',[rfReplaceAll]);

   if not StringControl(IpString) then
   begin
    Result := False;
    exit;
   end;

   Max_Range  := Max_IP_Count;
   IPGruplari := TStringList.Create;
   IPGruplari.Clear;

   // Birden Fazla IP Girildi İse
   if CharCount(IpString, GRUP_AYRAC) > 0 then
   begin
     // Virgül ile ayrılmış IP aralıklarını Ayırır.
     if IPGroupListSplit(IpString, IPGruplari) > 1 then
     begin
      // Satırları Gezer ve Aralıkları Hesaplar.
       for satir := 0 to IPGruplari.Count - 1 do
        if not IPv4Detect(IPGruplari[satir], List) then
         begin
         result := false;
         break;
         end;
     end;
   end
    else
    // Tek IP yada IP aralığı Girildi ise
    if not IPv4Detect(IpString, List) then
       result := false;

   if Assigned(IPGruplari) then
      IPGruplari.Free;

   if not Result then
      List.Clear;

 //Hesaplama süresi ölçülüyor.
  Calculate_Second := (GetTickCount-_Time)/1000;
  Ipv4Count := List.Count;

end;

end.

Kullanımı 

procedure TIPParserForm.ParseButtonClick(Sender: TObject);
begin

 IPList.Clear;
 info.Caption := 'IP Listesi Oluşturuluyor.Lütfen Bekleyiniz.';
 Application.ProcessMessages;
 ParseButton.Enabled := false;

 if not IPListCreate(IPsEdit.Text,Iplist.Items,adet.Value) then
  begin
    info.Caption := Error;
    IPsEdit.SetFocus;
  end
  else
  info.Caption := 'IP Listesi Oluşturuldu. Toplam IP : '+ IPv4Count.ToString+ ' Hesaplama Süresi : '+ Calculate_Second.ToString + ' sn';

  ParseButton.Enabled := true;
 end;


Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.

Sadece Hobiciyim..
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Taşınabilir uygulama aracı engerex 1 281 04-05-2019, Saat: 23:06
Son Yorum: Cyb3r
  Şifre Düzenleyici Uygulama witalihakko 11 2.527 01-11-2017, Saat: 17:24
Son Yorum: Hashshashin
  Türkiye Cumhuriyeti Merkez Bankası Kurları Mobil Uygulama YBSUzmani 1 1.018 19-07-2017, Saat: 11:25
Son Yorum: Fesih ARSLAN



Konuyu Okuyanlar: 1 Ziyaretçi