Форум: "Начинающим";
Текущий архив: 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.005 c