Всем доброго времени суток, мне необходимо перебрать определенный диапазон IP адресов. У меня допустим есть диапазон адресов 1.1.1.1-255.255.255.255 это если IPv4 я перебираю след. образом Код (Text): BYTE iCounterOfIP[4]; memset(iCounterOfIP,0,sizeof(iCounterOfIP)); memcpy(iCounterOfIP,FirstIP,sizeof(FirstIP)); int kPosition,mPosition,iPosition,jPosition = 3; while { ConnectAndCheck(iCounterOfIP); if (iCounterOfIP[jPosition]++ == LastIP[jPosition]) { iCounterOfIP[jPosition] = 0; kPosition = jPosition; if (iCounterOfIP[--kPosition]++ == LastIP[kPosition]) { iCounterOfIP[kPosition] = 0; mPosition = kPosition; if (iCounterOfIP[--mPosition]++ == LastIP[mPosition]) { iCounterOfIP[mPosition] = 0; iPosition = mPosition; if (iCounterOfIP[--iPosition]++ == LastIP[iPosition]) { iCounterOfIP[iPosition] = 0; break; } } } } } FirstIP - это массив 1.1.1.1 LastIP - собственно 255.255.255.255 но это для ip ver 4 а для ip ver 6 мне придется делать 16 условий (if ...) ? Какие есть способы более правильного перебора ? я понимаю что для ipv4 будет один способ, для ipv6 - другой. Заранее спасибо.
Ну, например: Код (Text): char start_ip[] = "127.0.0.1"; char end_ip[] = "127.0.1.5"; for(unsigned long i = htonl(inet_addr(start_ip)), j = htonl(inet_addr(end_ip)); i <= j; i++) { printf("%u.%u.%u.%u\n", (i>>24) & 0xFF, (i>>16) & 0xFF, (i>>8) & 0xFF, i & 0xFF); }
Только вот IPv6 ваша программа будет перебирать очень-очень долго. Ведь всего вариантов IPv6 - 2 ^ 128. Для оценки могу сказать, что если перебирать по одному миллиону адресов в секунду, то на полный перебор уйдут миллиарды лет. Вам придётся полностью менять алгоритм для IPv6, чтобы исключить полный перебор.
Kaimi ну это понятно можно сразу кидать ipv4 в DWORD менять местами октеты потом увеличивать и менять назад но такой вариант подходить наверно только ipv4 а какие есть варианты для ipv6 ?
Может для 6 применить подход - "по частям", "Может возьмете частями?" как-то сказал Шура Балаганов. )) Код (Text): ;В этой функции мы можем установить ограничения по перебору IP – адресов. ;В том варианте, что выше охвачен диапазон с 192.168.1.0 -192.168.1.17. seed dd 12345 IP db 20 dup(0) s_ip_start db "192.168.",0 p db '.' spc db 0 numBuffer db ? . . . ;============================================================ gen proc max_num:dword mov eax,08088405h xor edx,edx mul seed inc eax mov seed,eax mul max_num ret gen endp ;============================================================ ;============================================================ gen_IP proc uses ebx invoke Sleep,50 invoke GetTickCount mov seed,eax mov ebx,4 pushad invoke lstrcpy,ADDR IP,ADDR s_ip_start invoke gen,1 ; ------------------------------- 1 inc edx invoke dwtoa, edx, ADDR numBuffer invoke lstrcat,ADDR IP,ADDR numBuffer invoke lstrcat,ADDR IP,ADDR p invoke gen,17 ; ------------------------------- 17 inc edx invoke dwtoa, edx, ADDR numBuffer invoke lstrcat,ADDR IP,ADDR numBuffer invoke lstrcat,ADDR IP,ADDR spc popad ret gen_IP endp ;============================================================ . . . call gen_IP
KIV я согласен полностью. И не только для ipv6 для ipv4 2^32 на локальной машине вроде бистро а если еще что то с каждым делать то тоже долго будет . это да вот собственно и спрашиваю как правильно в принципе думаю так как и для ipv4.
Скажите полную задачу. Зачем вы сейчас хотите перебирать адреса? Потому что пока видно только одну задачу - "вывести все адреса". Такая задача, разумеется, решается только полным перебором.
Попробу распараллелить. Как-нибуть так: Код (Text): mov eax, $8000'0000 mov ecx, $9000'0000 mov edx, $a000'0000 mov edi, $b000'0000 mov esi, $c000'0000 mov ebx, $d000'0000 mov r8d, $e000'0000 mov r9d, $f000'0000 mov ebp, 1 @@: add eax, ebp add ecx, ebp add edx, ebp add edi, ebp add esi, ebp add ebx, ebp add r8d, ebp add r9d, ebp jnz @b mov eax, $1000'0000 mov ecx, $2000'0000 mov edx, $3000'0000 mov edi, $4000'0000 mov esi, $5000'0000 mov ebx, $6000'0000 mov r8d, $7000'0000 mov r9d, $8000'0000 @@: sub ecx, ebp sub edx, ebp sub edi, ebp sub esi, ebp sub ebx, ebp sub r8d, ebp sub r9d, ebp sub eax, ebp jnz @b У меня на компе скорость в разы быстрее чем: Код (Text): xor eax, eax @@: add eax, 1 jnz @b Хватит ли у тебя регистров? (ebp можно заменить на константу, esp заменяет r8 или r9) Ещё надо регистры чтобы делать dword IP -> asciiDec IP , безо всяких push pop . Так как у тебя диапазон то в конце циклов ещё будет CMP инструкция.
С ASCII важно знать сколько чисел (1,2,3) в каждых из четырёх частей. Код (Text): startIP db "20.20.100.1" endIP db "20.20.220.9" Увеличиваем 1 до тех пор пока она не станет равна 9ти. Если 100 != 220 то увеличиваем 100 на еденицу и запускаем цикл 1->9. если имеется такой вариант: Код (Text): startIP db "20.20.10.1" endIP db "20.20.220.9" то преобразуемего в такой: Код (Text): startIP db "20.20.10.1" middleIP_1 db "20.20.99.9" middleIP_2 db "20.20.100.1" endIP db "20.20.220.9" и работаем сначала по startIP+middleIP_1 а потом по middleIP_2+endIP очень не советую заниматься dword ip -> asciiDec ip преобразованием, очень долго.
Я надеюсь ты понял что более одного условия ни для ipv4 ни для ipv6 не надо в случае если мы не говорим об ascii.