Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.08.03;
Скачать: CL | DM;

Вниз

Алгоритм проверки правильности ввода ip-адреса   Найти похожие ветки 

 
БарЛог ©   (2008-06-07 15:01) [0]

Всем привет. Есть ли где-ньть готовый сабж?


 
oldman ©   (2008-06-07 15:03) [1]

Любой IP-адрес суть правильный.


 
БарЛог ©   (2008-06-07 15:03) [2]

ЗЫ. Ввод в эдит. Язык, практически, любой :)


 
БарЛог ©   (2008-06-07 15:04) [3]

> Любой IP-адрес суть правильный.
Имеется ввиду, что ввели "1.2.3.4", а не "1.2.3.256" и не "йцуйцуйцу"


 
oldman ©   (2008-06-07 15:12) [4]

И кто мешает по окончании ввода провериль Edit.Text посимвольно с анализом, матюгами и дурацкими советами пользователю?


 
wl ©   (2008-06-07 15:16) [5]

По моему, в винде есть компонент IPAddress, по крайней мере, если создать голое Win32 приложение в msvc, то его(IPAddress имеется в виду) можно поместить на диалог


 
den303 ©   (2008-06-07 15:17) [6]

TMaskEdit?


 
Игорь Шевченко ©   (2008-06-07 15:25) [7]


> Язык, практически, любой


define(REGEXP_IPv4,
"((1?\d?\d|2[0-4]\d|25[0-5])(\.(1?\d?\d|2[0-4]\d|25[0-5])){3 })");

function is_ipv4($i) {
return preg_match("/^".REGEXP_IPv4."$/",$i);
};

:)


 
ага   (2008-06-07 15:26) [8]


> БарЛог ©   (07.06.08 15:01)
>
> Всем привет. Есть ли где-ньть готовый сабж?
>

Конечно есть.
function inet_addr;         external    winsocket name "inet_addr";

If no error occurs, inet_addr returns an unsigned long value containing a suitable binary representation of the Internet address given. If the string in the cp parameter does not contain a legitimate Internet address, for example if a portion of an "a.b.c.d" address exceeds 255, then inet_addr returns the value INADDR_NONE.


 
oldman ©   (2008-06-07 15:26) [9]


> Игорь Шевченко ©   (07.06.08 15:25) [7]


Уважаю!

:))))))


 
Игорь Шевченко ©   (2008-06-07 15:27) [10]

За умение искать в Яндексе ? Право, не стоит


 
oldman ©   (2008-06-07 15:29) [11]

ты бы еще код мнемоникой в Яндексе нашел...
:)))


 
korneley ©   (2008-06-07 15:50) [12]

У Rouse был пример.
http://rouse.drkb.ru/network.php
"Получение информации о удаленном компьютере." Там как раз стандартный WC_IPADDRESS используется


 
БарЛог ©   (2008-06-07 15:54) [13]

Игорь Шевченко ©   (07.06.08 15:25) [7]
Кстати, такое тоже пригодится, ибо, приходится сталкиваться :) Спасибо.


 
antonn ©   (2008-06-07 15:57) [14]

для тех, кто по регуляркам встревает :)
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b


 
Пробегал2....   (2008-06-07 15:57) [15]

ага   (07.06.08 15:26) [8]
Конечно есть.
function inet_addr;         external    winsocket name "inet_addr";


вот самое правильное. Я так и делаю - сначала inet_addr проверяет является ли это IP-адресом, если нет - то считается что это хост, соотетственно, для него делается GetHostByName


 
Anatoly Podgoretsky ©   (2008-06-07 15:58) [16]

> БарЛог  (07.06.2008 15:04:03)  [3]

А если 12345678
Это тоже правильный адрес.
Копай в сторону АПИ там все это предусмотрено


 
БарЛог ©   (2008-06-07 16:07) [17]

Anatoly Podgoretsky ©   (07.06.08 15:58) [16]
> А если 12345678
> Это тоже правильный адрес.

В смысле, представленный в шестнадцатеричной СС?
Не, такого не надо :)


 
Anatoly Podgoretsky ©   (2008-06-07 16:13) [18]

> БарЛог  (07.06.2008 16:07:17)  [17]

В смысле представленый в Десятичной системы, кульхацкерам нравится.


 
vuk ©   (2008-06-08 03:17) [19]

А еще есть такая хрень. Если первая цифра в элементе ip адреса = 0 и в элементе нет цифр больше 7, то число трактуется, как записанное в восьмеричной системе счисления.

т.е. адрес 0177.0.0.1 = 127.0.0.1


 
vuk ©   (2008-06-08 03:25) [20]

Ну и еще, если октет начинается с символов "0x", система счисления считается за шестнадцатиричную. Как в двоичной заставить понимать - не помню, но как-то можно.


 
wl ©   (2008-06-08 03:43) [21]

из этого следует, что не стоит париться. если продвинутому ламеру потребуется двоичное представление айпи-адреса, но он по умолчанию способен сложить его в уме или в Калькуляторе в десятичную


 
Германн ©   (2008-06-08 03:50) [22]


> vuk ©   (08.06.08 03:17) [19]

Сколько лет, сколько зим! И Vuk проснулся!

Значит жива ещё старушка! :)


 
korneley ©   (2008-06-08 07:28) [23]


> vuk ©   (08.06.08 03:17) [19]
>  0177.0.0.1 = 127.0.0.1

Как это? Хоть в восьмеричной, хоть в девятиричной, но 177 = 177. А не 127. %)


 
@!!ex ©   (2008-06-08 07:57) [24]

> [23] korneley ©   (08.06.08 07:28)

177 в восмиричной == 127 в десятиричной


 
korneley ©   (2008-06-08 08:11) [25]


> @!!ex ©   (08.06.08 07:57) [24]
>177 в восмиричной == 127 в десятиричной

Дык, я же не о том... Я о визуализации числа. три цифры "177" не равны трем цифрам "127". В отдельно взятом контексте... :) Естественно, согласен, 177 восьмеричная запись = 127 - десятичная.


 
vuk ©   (2008-06-08 11:48) [26]

to wl ©   (08.06.08 03:43) [21]:
>из этого следует, что не стоит париться.
Из этого следует, что понятие правильно записанного IP адреса несколько шире. И если хочется сделать полноценную проверку, то, наверное, нужно учитывать все возможные форматы.

to korneley ©   (08.06.08 08:11) [25]:
>Дык, я же не о том... Я о визуализации числа.
А я о записи IP адреса.

>три цифры "177" не равны трем цифрам "127". В отдельно взятом
>контексте... :)
В отдельно взятом контексте (запись IP адреса) - равны.

copy/paste из консоли:

ping 0177.0.0.1
Обмен пакетами с 127.0.0.1 по 32 байт:
...


 
vuk ©   (2008-06-08 11:57) [27]

Поправлю малость сам себя.

>>три цифры "177" не равны трем цифрам "127". В отдельно взятом
>>контексте... :)
>В отдельно взятом контексте (запись IP адреса) - равны.
Там не 3 цифры, а 4 и 3. "0177" и "127". И вот эти варианты записи числа в данном конкретном контексте эквивалентны.


 
Marser ©   (2008-06-09 02:18) [28]

Вот, из личных поделок извращенца... Проверяет валидность ввода IPv4 и номера порта:

function validAdr(ipadr,portn:string):boolean;
var i,i1,c,c1,v:integer;
   ipa:string;
begin
 Result:=true;
 c:=0;
 c1:=0;
 i1:=0;
 ipa:=ipadr+".";//для упрощения работы цикла
 for i:=1 to length(ipa) do begin
   if ipa[i]="." then begin
     inc(c1);
     val(copy(ipa,i1+1,i-i1-1),v,c);
     i1:=i;
     if (byte(v)<>v)or(c>0)then //если больше одного байта или val дала ошибку
       result:=false;
   end;
 end;
 val(portn,v,c);
 if (c<>0)or (word(v)<>v)or(c1<>4) then result:=false;
end;


 
Пробегал2....   (2008-06-09 04:11) [29]

Marser ©   (09.06.08 2:18) [28]

абсолютно неправильный код. Если мы говорим о винде, то там есть функция inet_addr, она сама все распарсит. Читаем ветку...


 
korneley ©   (2008-06-09 07:10) [30]


> vuk ©  
> Там не 3 цифры, а 4 и 3.
>...
> copy/paste из консоли:ping 0177.0.0.1Обмен пакетами с 127.
> 0.0.1 по 32 байт:

Осознал, исправлюсь :) Кстати, функции из разных модулей (winsock и commctrl) по разному порядок октетов интерпретируют:
showmessage(inttohex(inet_addr("127.0.0.1"), 8) + " <> " + inttohex(MAKEIPADDRESS(127, 0, 0, 1), 8));


 
Style ©   (2008-06-09 12:17) [31]


> Игорь Шевченко ©   (07.06.08 15:25) [7]



> antonn ©   (07.06.08 15:57) [14]


IP адрес 0.0.0.0 семантически неверен
Надо опережающую негативную проверочку добавить ;)

    $reg = "^(?!0+\.0+\.0+\.0+\.$)(?>(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.){3}(?>[01]?\d\d?|2[0-4]\d|25[0-5])$";
   
    print "Text: ".htmlspecialchars($text)."<BR>";
    print "Regular: ".htmlspecialchars($reg)."<BR>";
    preg_match_all("/".$reg."/", $text, $matches, PREG_OFFSET_CAPTURE);
    print "Result: <BR><PRE>".htmlspecialchars(print_r($matches, true))."</PRE>";



 
Marser ©   (2008-06-16 04:17) [32]


> Пробегал2....   (09.06.08 04:11) [29]
> Marser ©   (09.06.08 2:18) [28]абсолютно неправильный код.
>  Если мы говорим о винде, то там есть функция inet_addr,
>  она сама все распарсит. Читаем ветку...

Бывает... Бывает, что и абсолютно неправильный код работает уже два года без единого промаха...


 
Пробегал2....   (2008-06-16 13:20) [33]

Marser ©   (16.06.08 4:17) [32]
Бывает, что и абсолютно неправильный код работает уже два года без единого промаха...


бывает. Но можно записать адрес:

0x7F.0.0.1

С точки зрения стандарта это будет правильный адрес. А с точки зрения твоей программы нет. И это некорректно, согласен?
Хотя бесспорно так адреса вводят редко, поэтому и за 10 лет ошибка может не вылезти.

При этом, чем больше пользователей у программы, тем чаще ты получаешь жалобы на несоблюдение каких-то общепринятых норм и правил. А если программа делается для 2-3 человек там вообще половину рекомендаций можно не соблюдать и не будет никаких жалоб.


 
Rouse_ ©   (2008-06-16 15:13) [34]

Пользуюсь таким кодом всегда и не парюсь :)

   InAddr := inet_addr(PChar(FAddress));
   if InAddr = INADDR_NONE then
   begin
     Host := gethostbyname(PChar(FAddress));
     if not Assigned(Host) then
     begin
       Error(WSAGetLastError, "TGSCustomClientSocket.Initialize -> Host := gethostbyname [Host = nil]");
       Exit;
     end;
     InAddr := PInAddr(Host.h_addr_list^)^.S_addr;
   end;


 
Пробегал2....   (2008-06-16 23:02) [35]

Rouse_ ©   (16.06.08 15:13) [34]

по-моему, там еще на assigned надо проверять и Host.h_addr_list после проверки самого Host.


 
DVM ©   (2008-06-16 23:11) [36]

function IsIP(const S: string): boolean;
var
 i: integer;
 DotCount: integer;
 NumVal: integer;
begin
 result := false;
 DotCount := 0;
 NumVal := 0;
 i := 1;
 while (i <= Length(S)) and (S[i] = " ") do Inc(i);
 if (i <= Length(S)) and (S[i] = ".") then exit;
 while i <= Length(S) do
   begin
     if S[i] = "." then
       begin
         inc(DotCount);
         if (DotCount > 3) or (NumVal > 255) then exit;
         NumVal := 0;
         if (i >= Length(S)) or (not (S[i + 1] in ["0".."9"])) then exit;
       end
     else
       if S[i] in ["0".."9"] then
         NumVal := NumVal * 10 + Ord(S[i]) - Ord("0")
       else
         begin
           while (i <= Length(S)) and (S[i] = " ") do Inc(i);
           if i <= Length(S) then exit;
           break;
         end;
     inc(i);
   end;
 if (DotCount <> 3) or (NumVal > 255) then exit;
 result := true;
end;


 
Пробегал2....   (2008-06-16 23:19) [37]

DVM ©   (16.06.08 23:11) [36]

нда. Долго писал? ;) А как тебе такой вариант:

function IsIP(const S: string): boolean;
begin
 if inet_addr(PChar(s)) = INADDR_NONE then Result := false
 else Result := true ;
end;


 
DVM ©   (2008-06-16 23:48) [38]


> Пробегал2....   (16.06.08 23:19) [37]


> нда. Долго писал? ;)

Это не я писал, да к тому же вариант не использует сокеты.

Сам я пользуюсь чем то вроде:

function InetAddr(const AHost: string): integer;
var
 PHost:PChar;
 HostEnt: PHostEnt;
begin
 if AHost = "" then
   result := INADDR_NONE
 else
   begin
     PHost := PChar(AHost);
     Result := inet_addr(PHost);
     if Result = INADDR_NONE then
       begin
         HostEnt := GetHostByName(PHost);
         if HostEnt <> nil then
           Result := integer(pointer(HostEnt^.h_addr^)^);
       end;
   end;
end;


 
DVM ©   (2008-06-16 23:52) [39]


> Пробегал2....   (16.06.08 23:19) [37]

Можно короче:

function IsIP(const S: string): boolean;
begin
 Result := not (inet_addr(PChar(s)) = INADDR_NONE);
end;


 
Simpson ©   (2008-06-17 12:21) [40]

antonn ©   (07.06.08 15:57) [14]
а словами как будет выглядеть эта регулярка?
а почему [0-9] вместо \d?
a почему [0-9][0-9] вместо \d{2}?

зы
Не стебусь, не понял эти моменты.



Страницы: 1 2 вся ветка

Текущий архив: 2008.08.03;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.024 c
2-1214037283
Grigoriy
2008-06-21 12:34
2008.08.03
Проблема с русским текстом при печати Tchart


15-1213613867
oxffff
2008-06-16 14:57
2008.08.03
Мы из космоса.


15-1213951578
palva
2008-06-20 12:46
2008.08.03
Знаете ли вы, что Ubuntu это на самом деле...


2-1215233515
Гриша
2008-07-05 08:51
2008.08.03
как сменить в откомпилированном файле значек(иконку) семерочки?


2-1215005230
ekto
2008-07-02 17:27
2008.08.03
передача параметра в процедуру