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

Вниз

Есть ли в Delphi функция проверки IP-адреса на валидность?   Найти похожие ветки 

 
SergP ©   (2011-10-04 16:56) [0]

Есть ли в Delphi функция проверки IP-адреса на валидность?

Я , конечно могу сам написать свою, но интересует именно наличие готовой.


 
И. Павел ©   (2011-10-04 16:59) [1]

> [0] SergP ©   (04.10.11 16:56)

А что вы подразумеваете под валидностью?
Если по адресу XXXX.XXXX.XXXX.XXXX ничего нет, то он валиден?


 
Dennis I. Komarov ©   (2011-10-04 16:59) [2]


> проверки IP-адреса на валидность?

В смысле? Значение IP или что?


 
RWolf ©   (2011-10-04 17:03) [3]

для невалидного адреса мы не сможем выяснить, есть по нему что-то или нет.


 
SergP ©   (2011-10-04 17:10) [4]

Имеется ввиду
> И. Павел ©   (04.10.11 16:59) [1]
>
> > [0] SergP ©   (04.10.11 16:56)
>
> А что вы подразумеваете под валидностью?
> Если по адресу XXXX.XXXX.XXXX.XXXX ничего нет, то он валиден?
>


Да нет... Мне не нужно проверять или такой адрес существует в сети. Просто проверить валидно ли значение.

например:
15.22.35.48 - валидно
12,25,25,12 - невалидно
352.15.25.22 - невалидно
127.0.1 - невалидно


 
Медвежонок Пятачок ©   (2011-10-04 17:16) [5]

Мне не нужно проверять или такой адрес существует в сети.

в сети существуют хосты, а не адреса.
адреса существуют в адресном пространстве.
причем все. и все они валидны.


 
SergP ©   (2011-10-04 17:17) [6]

Т.е. нужно выяснить, может ли строка является представлением IP-адреса в IPv4


 
Медвежонок Пятачок ©   (2011-10-04 17:23) [7]

ты в курсе, что строковых представлений не одно?
причем "666" - тоже валидное представление ИП адреса.


 
SergP ©   (2011-10-04 17:30) [8]

Имеется ввиду форма записи "Десятичная с точками"


 
Jeer ©   (2011-10-04 17:31) [9]

Опять проблемы с парсингом строки. :(


 
SergP ©   (2011-10-04 17:32) [10]

т.е. наиболее используемая при вводе пользователем и отображении пользователю.


 
Ega23 ©   (2011-10-04 17:35) [11]

Кроме IP есть ещё порт. Их тоже все проверять будешь на валидность?


 
SergP ©   (2011-10-04 17:36) [12]


> Jeer ©   (04.10.11 17:31) [9]
>
> Опять проблемы с парсингом строки. :(


Нет. Я же в [0] писал, что:


> Я , конечно могу сам написать свою, но интересует именно
> наличие готовой.


Просто когда есть что-то готовое, то нет смысла захламлять код своими вариантами таких функций.
Поэтому и пытаюсь узнать есть ли что-то готовое.
Если нет - напишу сам...


 
Jeer ©   (2011-10-04 17:39) [13]


> SergP ©   (04.10.11 16:56)  

За это вреся можно написать с десяток подобных функций и не захламлять форум :)

> SergP ©   (04.10.11 17:36) [12]


 
SergP ©   (2011-10-04 17:40) [14]


> Кроме IP есть ещё порт. Их тоже все проверять будешь на
> валидность?


Ну для порта проверок и не нужно, достаточно чтобы он был числом и умещался в word


 
Медвежонок Пятачок ©   (2011-10-04 17:42) [15]

Ну для порта проверок и не нужно

для адреса тоже самое, только dword.


 
Dennis I. Komarov ©   (2011-10-04 17:43) [16]

А ИП откуда берешь?


 
SergP ©   (2011-10-04 17:48) [17]


> Dennis I. Komarov ©   (04.10.11 17:43) [16]
>
> А ИП откуда берешь?


Пользователь вводит... Вот и нужно проверить, чтобы он не вел какую-то хрень.


 
Anatoly Podgoretsky ©   (2011-10-04 17:51) [18]

Лишь бы похоже было, а все остальное не важно.


 
Jeer ©   (2011-10-04 17:51) [19]

Где-то даже валялся компонент IP-Edit :)


 
pavel_guzhanov ©   (2011-10-04 17:52) [20]

Используй MaskEdit, он решит большую часть твоих проблем.


 
Dennis I. Komarov ©   (2011-10-04 17:56) [21]

дома валяется код, кажися Розыча, вроде даже не компонент, а виндовый...

если не выложат, то попозже...


 
Rouse_ ©   (2011-10-04 17:58) [22]

http://msdn.microsoft.com/en-us/library/ms738563%28VS.85%29.aspx


 
Rouse_ ©   (2011-10-04 18:03) [23]

А код в общем случае для получения InAddr примерно такой (данные представлены в виде IP адреса или UNC имени):

   InAddr := inet_addr(PChar(Addr));
   if InAddr = INADDR_NONE then
   begin
     Host := gethostbyname(PChar(Addr));
     if not Assigned(Host) then
     begin
//        OutputDebugString(PChar(Addr + " gethostbyname failed"));
       Exit;
     end;
//      OutputDebugString(PChar("gethostbyname = " + Addr));
     InAddr := PInAddr(Host.h_addr_list^)^.S_addr;
   end;


 
SergP ©   (2011-10-04 18:05) [24]


> Anatoly Podgoretsky ©   (04.10.11 17:51) [18]
>
> Лишь бы похоже было, а все остальное не важно.


Все остальное проверится потом.
Главное чтобы не вводили откровенной фигни...


 
DVM ©   (2011-10-04 18:23) [25]


>
> SergP ©   (04.10.11 16:56) 
> Есть ли в Delphi функция проверки IP-адреса на валидность?
>

TIdIPAddress


 
Омлет ©   (2011-10-04 18:55) [26]

Проверка на валидность + конвертация:

function StrToIP(const s: string; out IP: Longword): boolean;
var
 pCurChar: ^byte;
 prevChar: byte;
 i, dotCount: integer;
 x: longword;
begin
 Result := false;
 IP := 0;
 x := 0;
 dotCount := 0;
 pCurChar := @s[1];
 prevChar := ord(".");
 for i := length(s)-1 downto 0 do
 begin
   if (pCurChar^ >= ord("0")) and (pCurChar^ <= ord("9")) then
   begin
     x := x*10 + pCurChar^ - ord("0");
     if x > 255 then exit;
     if i = 0 then
     begin
       IP := IP shl 8 + x;
       Result := (dotCount = 3);
       exit;
     end;
   end
   else if pCurChar^ = ord(".") then
   begin
     if (dotCount = 3) or (prevChar = pCurChar^) then exit;
     inc(dotCount);
     IP := IP shl 8 + x;
     x := 0;
   end
   else exit;
   prevChar := pCurChar^;
   inc(pCurChar);
 end;
end;


 
Rouse_ ©   (2011-10-04 18:56) [27]


> Омлет ©   (04.10.11 18:55) [26]

Дык это все делается вызовом одной единственной АПИ :)
Rouse_ ©   (04.10.11 17:58) [22]


 
Rouse_ ©   (2011-10-04 18:58) [28]

зы: которая так-же учитывает следующие представления IP адреса:

Internet address value Meaning
"4.3.2.16"             Decimal
"004.003.002.020"      Octal
"0x4.0x3.0x2.0x10"     Hexadecimal
"4.003.002.0x10"       Mix


 
Омлет ©   (2011-10-04 19:07) [29]

> Rouse_ ©

WinAPI не кроссплатформенно ))

> Омлет ©   (04.10.11 18:55) [26]

Поправка
[+] контроль количества цифр, чтобы "0127.0.0.1" не прошел.

function StrToIP(const s: string; out IP: Longword): boolean;
var
 pCurChar: ^byte;
 prevChar: byte;
 i, dotCount, digitCount: integer;
 x: longword;
begin
 Result := false;
 IP := 0;
 x := 0;
 dotCount := 0;
 pCurChar := @s[1];
 digitCount := 0;
 prevChar := ord(".");
 for i := length(s)-1 downto 0 do
 begin
   if (pCurChar^ >= ord("0")) and (pCurChar^ <= ord("9")) then
   begin
     if digitCount = 3 then exit;
     inc(digitCount);
     x := x*10 + pCurChar^ - ord("0");
     if x > 255 then exit;
     if i = 0 then
     begin
       IP := IP shl 8 + x;
       Result := (dotCount = 3);
       exit;
     end;
   end
   else if pCurChar^ = ord(".") then
   begin
     if (dotCount = 3) or (prevChar = pCurChar^) then exit;
     inc(dotCount);
     IP := IP shl 8 + x;
     x := 0;
     digitCount := 0;
   end
   else exit;
   prevChar := pCurChar^;
   inc(pCurChar);
 end;
end;


 
Dennis I. Komarov ©   (2011-10-04 19:11) [30]

uses
comctrls, commctrl;
type
TIPEdit = class(TWinControl)
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMGetDlgCode( var Message:TWMGetDlgCode); message WM_GETDLGCODE;
end;
procedure TIPEdit.CreateParams(var Params: TCreateParams);
begin
InitCommonControl(ICC_INTERNET_CLASSES );
inherited CreateParams(Params);
CreateSubClass(Params, WC_IPADDRESS);
Params.Style := Params.Style or WS_TABSTOP;
end;
procedure TIpEdit.WMGetDlgCode;
begin
inherited;
Message.Result := Message.result or DLGC_WANTARROWS; // and not DLGC_WANTTAB;
end;
var Edit1: TIPEdit;
procedure TForm1.FormCreate(Sender: TObject);
begin
if not Assigned(Edit1) then begin
Edit1 := TIPEdit.Create(Self);
with Edit1 do
begin
Name := "Edit1";
Parent := Self;
Left := 24;
Top := 16;
Width := 121;
Height := 21;
Tabstop := True;
end;
SendMessage(Edit1.Handle,IPM_CLEARADDRESS,0,0);
SendMessage(Edit1.Handle,IPM_SETADDRESS,0,MAKEIPADDRESS(127,0,0,1));
end;
end;


Не помню чей (to Rouse_ вроде твой, но могу ошибаться), но кого-то из мастеров. Если интересно, можно на .net поискать, так что на авторство не претендую :)


 
Rouse_ ©   (2011-10-04 19:13) [31]


> Омлет ©   (04.10.11 19:07) [29]
> WinAPI не кроссплатформенно ))

Ну тогда правь ошибки :) Например оть тут будет вылет при пустой строке:
pCurChar := @s[1];
:)


 
Rouse_ ©   (2011-10-04 19:15) [32]


> Dennis I. Komarov ©   (04.10.11 19:11) [30]

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


 
Rouse_ ©   (2011-10-04 19:24) [33]

А, не, это код от Leonid Troyanovsky.
У меня вот так было: http://forum.sources.ru/index.php?showtopic=173391


 
Омлет ©   (2011-10-04 19:24) [34]

> Rouse_ ©   (04.10.11 19:13) [31]

fixed + support unicoded Delphi.

function StrToIP(const strIP: AnsiString; out uintIP: Longword): boolean;
var
 pCurChar: ^byte;
 prevChar: byte;
 i, dotCount, digitCount: integer;
 x: longword;
begin
 Result := false;
 if strIP = "" then exit;
 uintIP := 0;
 x := 0;
 dotCount := 0;
 pCurChar := @strIP[1];
 digitCount := 0;
 prevChar := ord(".");
 for i := length(strIP)-1 downto 0 do
 begin
   if (pCurChar^ >= ord("0")) and (pCurChar^ <= ord("9")) then
   begin
     if digitCount = 3 then exit;
     x := x*10 + pCurChar^ - ord("0");
     if x > 255 then exit;
     if i = 0 then
     begin
       uintIP := uintIP shl 8 + x;
       Result := (dotCount = 3);
       exit;
     end;
     inc(digitCount);
   end
   else if pCurChar^ = ord(".") then
   begin
     if (dotCount = 3) or (prevChar = pCurChar^) then exit;
     inc(dotCount);
     uintIP := uintIP shl 8 + x;
     x := 0;
     digitCount := 0;
   end
   else exit;
   prevChar := pCurChar^;
   inc(pCurChar);
 end;
end;


 
Rouse_ ©   (2011-10-04 19:31) [35]


> Омлет ©   (04.10.11 19:24) [34]
>
> > Rouse_ ©   (04.10.11 19:13) [31]
>
> fixed + support unicoded Delphi.

А обниливание результата при ошибке? :)
Writeln(StrToIP("255.255,255.255", D));


 
Rouse_ ©   (2011-10-04 19:32) [36]

точнее:

var
 D: Cardinal;
begin
 Writeln(StrToIP("255.255,255.255", D));
 writeln(D);
 readln;
end.

255 кажет ;)


 
Омлет ©   (2011-10-04 19:38) [37]

> Rouse_ ©   (04.10.11 19:31) [35]
> А обниливание результата при ошибке? :)


Обнуление? Зачем? Это же out, а не var..

if StrToIP("255.255,255.255", D) then
 continue and use D
else
 invalid IP


 
Rouse_ ©   (2011-10-04 19:42) [38]


> Омлет ©   (04.10.11 19:38) [37]
> Обнуление? Зачем?

Затем что всегда найдется индивидум, который не проверит результат :)


 
Омлет ©   (2011-10-04 19:51) [39]

> Затем что всегда найдется индивидум, который не проверит результат

Ок, подстрахуемся.

function StrToIP(const strIP: AnsiString; out uintIP: Longword): boolean;
var
 pCurChar: ^byte;
 prevChar: byte;
 i, dotCount, digitCount: integer;
 x: longword;
begin
 if strIP <> "" then
 begin
   uintIP := 0;
   x := 0;
   dotCount := 0;
   pCurChar := @strIP[1];
   digitCount := 0;
   prevChar := ord(".");
   for i := length(strIP)-1 downto 0 do
   begin
     if (pCurChar^ >= ord("0")) and (pCurChar^ <= ord("9")) then
     begin
       if digitCount = 3 then break;
       x := x*10 + pCurChar^ - ord("0");
       if x > 255 then break;
       if i = 0 then
       begin
         if dotCount <> 3 then break;
         uintIP := uintIP shl 8 + x;
         Result := true;
         exit;
       end;
       inc(digitCount);
     end
     else if pCurChar^ = ord(".") then
     begin
       if (dotCount = 3) or (prevChar = pCurChar^) then break;
       inc(dotCount);
       uintIP := uintIP shl 8 + x;
       x := 0;
       digitCount := 0;
     end
     else break;
     prevChar := pCurChar^;
     inc(pCurChar);
   end;
 end;
 Result := false;
 uintIP := 0;
end;


 
Rouse_ ©   (2011-10-04 19:54) [40]

Зы: кстати по поводу разделения результата и возвращаемого значения, я сам так периодически делаю, но давно пришел к выводу что это есть не правильный подход и сейчас себя приучаю не писать функции вида:
function Foo(out/var OutputValue): Boolean
ибо гораздо правильней делать
function Foo: OutputValue
убирается избыточность, а проверку лучше по самому возращенному значению делать...


 
Rouse_ ©   (2011-10-04 19:55) [41]

т.е. в твоем случае это будет полный аналог inet_addr с результатом INADDR_NONE в случае ошибки.
(ну это так - в качестве брюзжания :)


 
Омлет ©   (2011-10-04 20:01) [42]

> Rouse_ ©   (04.10.11 19:55) [41]

А разве адрес 0.0.0.0 невалидный?


 
Rouse_ ©   (2011-10-04 20:06) [43]

INADDR_NONE это не 0.0.0.0, это аналог броадкаст адреса, т.е. INADDR_BROADCAST
Такие случаи оговариваются в спецификации и в случае, если мы явно знаем что нужен броадкаст, идет проверка именно на него.


 
Омлет ©   (2011-10-04 20:11) [44]

> Rouse_ ©   (04.10.11 20:06) [43]

Я к тому, что по результату функции

function StrToIP(const s: string): dword;

никак не понять, валидный адрес или нет. Поэтому приходится вводить out-параметр.


 
Rouse_ ©   (2011-10-04 20:17) [45]

Почему? Понять... возвращай INADDR_NONE в случае ошибки.
Единственно конфликт будет с адресом 255.255.255.255, но это будет уже ошибка программиста, который зная о существовании константы INADDR_BROADCAST не воспользовался ей и попробовал произвести конвертацию IP адреса через функцию.


 
Омлет ©   (2011-10-04 20:32) [46]

> Rouse_ ©   (04.10.11 20:17) [45]

Вот именно, что будет конфликт. Пользователь ввел адрес 255.255.255.255, а нам надо проверить валидность..
Мы смотрим - INADDR_NONE, ага, невалидный - пользователь в недоумении )


 
Anatoly Podgoretsky ©   (2011-10-04 20:43) [47]


> Rouse_ ©   (04.10.11 19:55) [41]

Так почему бы не использовать именно inet_addr


 
Rouse_ ©   (2011-10-04 20:59) [48]


> Омлет ©   (04.10.11 20:32) [46]
>
> > Rouse_ ©   (04.10.11 20:17) [45]
>
> Вот именно, что будет конфликт.

Не будет, нет-же ни у кого из разработчиков сетевого транспорта проблем с inet_addr :)


> Anatoly Podgoretsky ©   (04.10.11 20:43) [47]
> Так почему бы не использовать именно inet_addr

Дык я его изначально и предлагал в 22-ом посте :)


 
Anatoly Podgoretsky ©   (2011-10-04 21:15) [49]

> Rouse_  (04.10.2011 20:59:48)  [48]

Так ты предложил в форме ссылке, а я ее не смотрел.


 
Rouse_ ©   (2011-10-04 21:18) [50]

Ну в 23-ем тоже его предложил :)


 
DVM ©   (2011-10-04 22:20) [51]


> Омлет ©   (04.10.11 19:51) [39]

теперь ждем для IPv6 :)



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

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

Наверх




Память: 0.61 MB
Время: 0.01 c
2-1316525951
istok20
2011-09-20 17:39
2012.01.08
посоветуйте компонент для галереи...


2-1317272307
Gu
2011-09-29 08:58
2012.01.08
передний план


2-1317565266
Pcrepair
2011-10-02 18:21
2012.01.08
TWebBrowser обрабатывает JAVA с ошибкой


15-1316041496
Кто б сомневался
2011-09-15 03:04
2012.01.08
Кто там говорил что человек не биоробот?


15-1316774640
К-111
2011-09-23 14:44
2012.01.08
Что нужно знать, чтобы выполнить ТЗ?