Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.01.08;
Скачать: [xml.tar.bz2];

Вниз

Есть ли в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.59 MB
Время: 0.004 c
2-1317480831
Mishanja
2011-10-01 18:53
2012.01.08
Выделение строки в ListView


2-1317359287
Natalie
2011-09-30 09:08
2012.01.08
Как отобразить в Memo тест длинною 4000 символов?


2-1317454345
vgvolk
2011-10-01 11:32
2012.01.08
Разворачивание окна автоматически


15-1316516688
KSergey
2011-09-20 15:04
2012.01.08
Как организована продажа игровых артефакт, "вирт. валюты сайтов"


2-1317392685
Сергей
2011-09-30 18:24
2012.01.08
Как выполнить репликацию Access c помощью Delphi?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский