Har senaste tiden skrivit en del kod som är tänkt att processa information från flera nätverksnoder. Därför behövde jag ett bra sätt att få fram alla ipadresser mellan en given start- och slut-adress. Kollade runt på nätet och hittade inte mycket om det så jag satte mig ner och testade följande:
long
startIP = (long)(uint)IPAddress.HostToNetworkOrder((int)IPAddress.Pars(tbStartIP.Text).Address);
long endIP = (long)(uint)IPAddress.HostToNetworkOrder((int)IPAddress
.Parse(tbEndIP.Text).Address);
ArrayList ipaddresses = new ArrayList
();
for (long i = startIP; i <= endIP; i++) { ipaddresses.Add(CalcIPAddressFromIPNumber(i)); }private
string CalcIPAddressFromIPNumber(long ipnumber)
{
string retval;
long w = (ipnumber / 16777216) % 256;
long x = (ipnumber / 65536) % 256;
long y = (ipnumber / 256) % 256;
long z = (ipnumber) % 256;
retval = string.Format(”{0}.{1}.{2}.{3}”, new string[] { w.ToString(), x.ToString(), y.ToString(), z.ToString() });
return retval;
}
Det funkade helt perfekt dock är det väldigt mycket boxning och parsning vilket kan resultera i mycket overhead. I detta exempel, som rent kodfiness mässigt är bland det snyggare av de olika varianterna, används ju division av heltal i stor utsträckning vilket är enkelt för processorn att hantera.
Nästa exempel ser ut som följer:
long
startIP = (long)(uint)IPAddress.HostToNetworkOrder((int)IPAddress.Pars(tbStartIP.Text).Address);
long endIP = (long)(uint)IPAddress.HostToNetworkOrder((int)IPAddress.Parse(tbEndIP.Text).Address);
ArrayList ipaddresses = new ArrayList();
for (long i = startIP; i <= endIP; i++) { ipaddresses.Add(IPAddress.Parse(i.ToString()).ToString());
}
Här använder jag de redan färdigskrivna funktionerna, parsningar m.m som finns på IPAddress klassen i .Net. Har inte kört reflector och kollar men jag skulle misstänka att den i bakrunden gör något i still med mitt förra exempel när man ropar på parse. Denna kod är mindre snygg eftersom det är väldigt mycket string hantering fram och tillbaka vilket blir väldigt bluddrigt.
Sista exemplet, och även det som exikverar snabbast:
private
ArrayList CalculateIPAddresses(string startIP, string endIP)
{
ArrayList retval = new ArrayList();
// Split ip addresses
string[] arrStartIP = startIP.Split(new string[] { ”.” }, StringSplitOptions.None);
string[] arrEndIP = endIP.Split(new string[] { ”.” }, StringSplitOptions.None);
// Get int values from ip
int StartIP1 = int.Parse(arrStartIP[0]);
int StartIP2 = int.Parse(arrStartIP[1]);
int StartIP3 = int.Parse(arrStartIP[2]);
int StartIP4 = int.Parse(arrStartIP[3]);
int EndIP1 = int.Parse(arrEndIP[0]);
int EndIP2 = int.Parse(arrEndIP[1]);
int EndIP3 = int.Parse(arrEndIP[2]);
int EndIP4 = int.Parse(arrEndIP[3]);
// Set calc values
int StartIP2Calc = 0;
int StartIP3Calc = 0;
int StartIP4Calc = 0;
int EndIP2Calc = 0;
int EndIP3Calc = 0;
int EndIP4Calc = 0;
// Start looping the first segment
for (int i = StartIP1; i <= EndIP1; i++) { // Calc values for next enumeration
if ((i > StartIP1) && (i <>// Middle of loop of first segment
StartIP2Calc = 0;
EndIP2Calc = 254;
}
else if ((i == StartIP1) && (i == EndIP1))
{
// Only one rotation of the first segment
// Set start and end point to actual values
StartIP2Calc = StartIP2;
EndIP2Calc = EndIP2;
}
else if (i == StartIP1)
{
// First rotation of the first segment
// start at starting ip of second segment
StartIP2Calc = StartIP2;
EndIP2Calc = 254;
}
else if (i == EndIP1)
{
// Last rotation of the first segment
// End at the last specified ip of second segment
StartIP2Calc = 0;
EndIP2Calc = EndIP2;
}
// Start looping
for (int j = StartIP2Calc; j <= EndIP2Calc; j++) { // Calc values for next enumeration
if ((j > StartIP2Calc) && (j <>// Middle of loop of this segment
StartIP3Calc = 0;
EndIP3Calc = 254;
}
else if ((j == StartIP2Calc) && (j == EndIP2Calc))
{
// Only one rotation of second segment
// Set start and end point to actual values
StartIP3Calc = StartIP3;
EndIP3Calc = EndIP3;
}
else if (j == StartIP2Calc)
{
// First rotation of the second segment
// Start at the starting ip of third segment
StartIP3Calc = StartIP3;
EndIP3Calc = 254;
}
else if ((j == EndIP2Calc) && (i==EndIP1))
{
// Last rotation of the first segment
// Last rotation of the second segment
// End at the last specified ip of third segment
StartIP3Calc = 0;
EndIP3Calc = EndIP3;
}
// Start loop of third segment
for (int k = StartIP3Calc; k <= EndIP3Calc; k++) { // Calc values for next enumeration
if ((k > StartIP3Calc) && (k <>{
// Middle of loop for the segment
StartIP4Calc = 1;
EndIP4Calc = 254;
}
else if ((k == StartIP3Calc) && (k == EndIP3Calc))
{
// Only rotation of third segment
// Set start and end point to actual values
StartIP4Calc = StartIP4;
EndIP4Calc = EndIP4;
}
else if (k == StartIP3Calc)
{
// First segment of the third segment
// Start at the starting ip of fourth segment
StartIP4Calc = StartIP4;
EndIP4Calc = 254;
}
else if ((k == EndIP3Calc) && (j==EndIP2Calc) && (i==EndIP1))
{
// Last segment of the third segment
// End at the last specified ip of the four segment
StartIP4Calc = 1;
EndIP4Calc = EndIP4;
}
// Start loop of fourth segment
for (int l = StartIP4Calc; l <= EndIP4Calc; l++) { // Add ip address to arraylist
retval.Add(string.Format(”{0}.{1}.{2}.{3}”, new string[] { i.ToString(), j.ToString()
,k.ToString(), l.ToString() }));
}
}
}
}
return retval;
}
Kodmässigt är denna variant riktigt vidrig! Dock är det den absolut snabbaste! Vid framräkning av alla adresser mellan 192.167.20.1 -> 192.168.10.1 så var den 0.2 sekunder. Inte direkt så mycket att det spelar någon större roll, men ändå! Troligen är det för att det ändast sker upräkning av ett siffer serie i taget istället för en massa parsning/divisioner varje interation. Om det är någon som kan beskriva detta i mer detalj så kommentera gärna.