![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Есть ли в Delphi функция проверки IP-адреса на валидность? [D7, XP]
SergP © (2011-10-04 16:56:00)Есть ли в Delphi функция проверки IP-адреса на валидность?
Я , конечно могу сам написать свою, но интересует именно наличие готовой.
DVM (2011-10-04 22:20:00) [1]
> Омлет © (04.10.11 19:51) [39]
теперь ждем для IPv6 :)
Rouse_ (2011-10-04 21:18:00) [2]Ну в 23-ем тоже его предложил :)
Anatoly Podgoretsky (2011-10-04 21:15:00) [3]> Rouse_ (04.10.2011 20:59:48) [48]
Так ты предложил в форме ссылке, а я ее не смотрел.
Rouse_ (2011-10-04 20:59:00) [4]
> Омлет © (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 20:43:00) [5]
> Rouse_ © (04.10.11 19:55) [41]
Так почему бы не использовать именно inet_addr
Омлет (2011-10-04 20:32:00) [6]> Rouse_ © (04.10.11 20:17) [45]
Вот именно, что будет конфликт. Пользователь ввел адрес 255.255.255.255, а нам надо проверить валидность..
Мы смотрим - INADDR_NONE, ага, невалидный - пользователь в недоумении )
Rouse_ (2011-10-04 20:17:00) [7]Почему? Понять... возвращай INADDR_NONE в случае ошибки.
Единственно конфликт будет с адресом 255.255.255.255, но это будет уже ошибка программиста, который зная о существовании константы INADDR_BROADCAST не воспользовался ей и попробовал произвести конвертацию IP адреса через функцию.
Омлет (2011-10-04 20:11:00) [8]> Rouse_ © (04.10.11 20:06) [43]
Я к тому, что по результату функции
function StrToIP(const s: string): dword;
никак не понять, валидный адрес или нет. Поэтому приходится вводить out-параметр.
Rouse_ (2011-10-04 20:06:00) [9]INADDR_NONE это не 0.0.0.0, это аналог броадкаст адреса, т.е. INADDR_BROADCAST
Такие случаи оговариваются в спецификации и в случае, если мы явно знаем что нужен броадкаст, идет проверка именно на него.
Омлет (2011-10-04 20:01:00) [10]> Rouse_ © (04.10.11 19:55) [41]
А разве адрес 0.0.0.0 невалидный?
Rouse_ (2011-10-04 19:55:00) [11]т.е. в твоем случае это будет полный аналог inet_addr с результатом INADDR_NONE в случае ошибки.
(ну это так - в качестве брюзжания :)
Rouse_ (2011-10-04 19:54:00) [12]Зы: кстати по поводу разделения результата и возвращаемого значения, я сам так периодически делаю, но давно пришел к выводу что это есть не правильный подход и сейчас себя приучаю не писать функции вида:
function Foo(out/var OutputValue): Boolean
ибо гораздо правильней делать
function Foo: OutputValue
убирается избыточность, а проверку лучше по самому возращенному значению делать...
Омлет (2011-10-04 19:51:00) [13]> Затем что всегда найдется индивидум, который не проверит результат
Ок, подстрахуемся.
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:42:00) [14]
> Омлет © (04.10.11 19:38) [37]
> Обнуление? Зачем?
Затем что всегда найдется индивидум, который не проверит результат :)
Омлет (2011-10-04 19:38:00) [15]> 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:32:00) [16]точнее:
var
D: Cardinal;
begin
Writeln(StrToIP('255.255,255.255', D));
writeln(D);
readln;
end.
255 кажет ;)
Rouse_ (2011-10-04 19:31:00) [17]
> Омлет © (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:24:00) [18]А, не, это код от Leonid Troyanovsky.
У меня вот так было: http://forum.sources.ru/index.php?showtopic=173391
Омлет (2011-10-04 19:24:00) [19]> 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:15:00) [20]
> Dennis I. Komarov © (04.10.11 19:11) [30]
Мой, только с ним проблема, не получилось его у меня в виде нормального контрола сделать, постоянно слетало что-то, поэтому тут создание в динамике было сделано...