Форум программистов, компьютерный форум, киберфорум
Delphi: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
130 / 109 / 22
Регистрация: 23.05.2015
Сообщений: 736
RAD XE3+

Как распарсить IP адрес регулярным выражением

05.09.2022, 21:43. Показов 3389. Ответов 26

Студворк — интернет-сервис помощи студентам
Решил получить внешний IP адрес. (опять мой код который работал под D7 - перестал работать на D11 ) и я начал искать альтернативу и нашел:

Пример чисто тестовый.
Часть кода взята отсюда


Работу со строкой наваял сам.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{ Внешний IP адрес по материалам видео
https://www.youtube.com/watch?v=QfRWhBdLrUA }
procedure TForm1.Button1Click(Sender: TObject);
var
  i : Integer;
  s, ip : String;
begin
 
s:= IDHTTP1.GET('http://checkip.dyndns.com/');
  For i:=1 To Length(s) Do
   begin
    If s[i] In ['0'..'9','.'] Then
     ip:=ip+s[i];
   end;
  Form1.Caption:=ip; //сам адрес
End;
Знаю что того же эффекта можно добиться таким регулярным выражением:

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d {1,3})
или так:
((?:\d{1,3}\.){3}\d{1,3})
Это то же, из материалов форума

Но как, не знаю, то что мне удавалось найти было похоже на огромные простыни.
Сам, с регулярными выражениями никогда не работал, если знаете как плиз подскажите.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.09.2022, 21:43
Ответы с готовыми решениями:

Разложить адрес по частям не регулярным выражением
Здравствуйте. Есть адреса поступающие из Prom ua. Они отличаются по формату друг от друга. Вот примеры разных форматов какие могут...

Как выбрать стиль регулярным выражением
Всем привет! Столкнулся с такой проблемой, нужно выбрать стиль регулярным выражением. Задача такая. Вот есть у нас некий стиль ...

Как проверить регулярным выражением цифру?
Всем привет! Нужно проврить переменную, имеет она значение 1 или 0 проверяется через test делал так но тогда пропускает цифру 11 ...

26
130 / 109 / 22
Регистрация: 23.05.2015
Сообщений: 736
21.04.2023, 09:11  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от AzAtom Посмотреть сообщение
функция в этой переменной вернёт найденный IP-адрес.
Пример вызова можно узреть.
Адрес явно String, в функции Cardinal объявлен - простите не догоняю.
0
Нарушитель
10901 / 5835 / 1289
Регистрация: 12.03.2015
Сообщений: 26,926
21.04.2023, 09:18
Вот вам мой рукожопный модуль из текущего (и предыдущих) проекта (проектов). Может чаво-нить из него наведёт на нужные мысли.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
unit uWinSockUtils;
 
interface
 
{$REGION 'uses'}
uses
  //============================== Модули проекта ==============================
  uRoutines,
  //=================== Системные модули, добавленные вручную ==================
  Windows, WinSock, SysUtils, StrUtils;
{$ENDREGION}
 
{$REGION 'const'}
const
  ADAPTERS_BUFFER_SIZE    = 8192; // 8 кбайт хватит?
  MAX_ETHERNET_FRAME_SIZE = 1514; // максимальная длина ethernet-пакета (почему именно такая?)
{$ENDREGION}
 
{$REGION 'общие типы данных'}
type
  {$REGION 'TMacAddress'}
  TMacAddr48 = packed array[0..5] of Byte;
  TMacAddress = record
  private
    function get_as_text: string;
    procedure set_as_text(const text: string); // преобразование строки вида ХХ:ХХ:ХХ:ХХ:ХХ:ХХ в мас-адрес
  public
    const DELIMS = ' .:;-|='; // возможные разделители
  public
    function is_zero: boolean;
    procedure copy_from(const addr: pointer); // копирование данных в структуру
    class function validate(const text: string): boolean; static; // проверка мас-адрес-строки на валидность
    class operator Equal(const mac1, mac2: TMacAddress): Boolean; // сравнение
  public
    property as_text: string read get_as_text write set_as_text;
  case Boolean of
    False: (Bytes: TMacAddr48);
    True:  (A0, A1, A2, A3, A4, A5: Byte);
  end;
 
  // проверка размера
  {$IF sizeof(TMacAddress) <> sizeof(TMacAddr48)} {$MESSAGE FATAL 'Size mismatch'} {$ENDIF}
  {$ENDREGION}
 
  {$REGION 'TIpAddress_v4'}
  TIPv4SubnetClass = (SUBNET_CLASS_A, SUBNET_CLASS_B, SUBNET_CLASS_C, SUBNET_CLASS_D, SUBNET_CLASS_E);
  TIPv4 = packed array[0..3] of Byte;
  TIpAddress_v4 = packed record
  private
    function get_as_text: string;
    procedure set_as_text(const text: string); // преобразование строки вида a.b.c.d в IPv4-адрес
    function get_subnet_class: TIPv4SubnetClass; inline; // класс подсети
  public
    const DELIMS = ' .'; // возможные разделители
  public
    procedure copy_from(const addr: pointer); // копирование данных в структуру
    function same_subnet(const ip: TIpAddress_v4): Boolean; // проверка на принадлежность адреса той же подсети, что и сам  (+03 мар 2021)
    class function validate(const text: string): boolean; static; // проверка IP-адрес-строки на валидность
    class operator Equal(const ip1, ip2: TIpAddress_v4): Boolean; // сравнение
  public
    property as_text: string read get_as_text write set_as_text;
    property subnet_class: TIPv4SubnetClass read get_subnet_class; // класс подсети
  case Integer of
    0: (Value: DWORD);
    1: (dwRec: TDWordRec);
    2: (Bytes: TIPv4);
    3: (B0, B1, B2, B3: Byte);
    4: (in_addr: TInAddr);
  end;
 
  // проверка размера
  {$IF sizeof(TIpAddress_v4) <> sizeof(TIPv4)} {$MESSAGE FATAL 'Size mismatch'} {$ENDIF}
  {$ENDREGION}
 
  {$REGION 'TIpAddress_v6'}
  TIPv6 = packed array[0..16] of Byte; // 16 байт + 1 (// 17 байт - FE80 0000 0000 0000 65E5 C2B5 C63B DD50 % 03)
  TIpAddress_v6 = packed record
  public
    function get_as_text: string;
    procedure copy_from(const addr: pointer); // копирование данных в структуру
  case Integer of
    0: (Prefix, IID: TQWordRec; Suffix: Byte);
    1: (Bytes: TIPv6);
  end;
 
  // проверка размера
  {$IF sizeof(TIpAddress_v6) <> sizeof(TIPv6)} {$MESSAGE FATAL 'Size mismatch'} {$ENDIF}
  {$ENDREGION}
 
  {$REGION 'Ethernet-буфер (14 байт)'}
  // Ethernet-буфер (14 байт)
  PEthernetFrame = ^TEthernetFrame;
  TEthernetFrame = packed record
    DestAddress:   TMacAddress;          // Destination Address - здесь находится информация
                                         // о физическом (далее MAC) адресе хоста-приемника.
    SourceAddress: TMacAddress;          // Source Address - информация о MAC
                                         // (Media Access Control) адресе источника.
    EtherType:      WORD;                // EtherType - тип Ethernet среды
                                         // (это может быть Ethernet, Token Ring, Frame relay, ATM).
    //PayLoad:        array[0..0] of Byte; // Payload - это поле, по сути, является полезной нагрузкой
                                         //  - может содержать все что угодно.
                                         // Если мы хотим послать ARP пакет, то в этом поле
                                         // должна содержаться полная информация ARP кадра,
                                         // то есть его заголовок и его полезная нагрузка.
  end;
  {$ENDREGION}
 
  {$REGION 'ARP-буфер (28 байт)'}
  PArpFrame = ^TArpFrame;
  TArpFrame = packed record
    HardwareType:   Word;        // Hardware Type - указывает на тип канала связи данных
                                 // (Ethernet, Token Ring, Framerelay, ATM).
    ProtocolType:   Word;        // Protocol Type - содержит тип протокола.
                                 // В нашем случае это ARP протокол.
    HardAddrLength: Byte;        // Hardware Address Length - содержит длину
                                 // поля физического адреса (MAC адреса).
    ProtAddrLength: Byte;        // Protocol Address Length - содержит длину
                                 // поля протокольного адреса (IP адреса).
    Operation:      Word;        // Operation - указывает на тип ARP кадра.
                                 // Это может  быть кадр запроса, кадр ответа,
                                 //  и обратные варианты запроса и ответа.
    SenderHardAddr: TMacAddress; // Sender Hardware Address - сюда записывается MAC адрес отправителя.
    SenderProtAddr: TIpAddress_v4;  // Sender Protocol Address - в него записывается IP адрес отправителя.
    TargetHardAddr: TMacAddress; // Target Hardware Address - соответственно MAC адрес получателя.
    TargetProtAddr: TIpAddress_v4;  // Target Protocol Address - соответственно IP адрес получателя.
  end;
  {$ENDREGION}
 
  {$REGION 'статический буфер приёма/передачи'}
  TFrameBuff = array[0..MAX_ETHERNET_FRAME_SIZE - 1] of Byte;
  PFrameBuffer = ^TFrameBuffer;
  TFrameBuffer = packed record
  case Byte of
    0: (Bytes: TFrameBuff);
    1:
    (
      EthernetFrame: TEthernetFrame;
      ArpFrame:      TArpFrame;
      PayLoad:       array[0..0] of Byte; // начало хвоста (данные)
    );
  end;
  {$ENDREGION}
{$ENDREGION}
 
{$REGION 'прототипы'}
function inet_addr(const ws: string): DWORD;
function inet_ntoa(inaddr: TInAddr): string;
function GetHostByName(const wname: string): PHostEnt;
function GetHostName(var wname: string): Integer;
function GetServByName(wname, wproto: string): PServEnt;
function GetLocalIP: string;
function IpToStr(const dw: DWORD): string;
function TInAddrStructToText(A: TInAddr): string;
function TryStrToIp(const s: string; out A: TInAddr): Boolean;
function WinSockErrorToString(err: Integer): string;
procedure DNSLookup(Address: string; var HostName, IP: string);
function Get_Inet_Addr(Addr: string): Integer;
function RevertW(const w: WORD): WORD; inline;
function RevertDW(const dw: DWORD): DWORD; inline;
{$ENDREGION}
 
implementation
 
{$REGION 'TMacAddress'}
{ TMacAddress }
 
procedure TMacAddress.copy_from(const addr: pointer);
begin
  // копирование данных в структуру
  move(pbyte(addr)^, self, sizeof(self));
end;
 
class operator TMacAddress.Equal(const mac1, mac2: TMacAddress): Boolean;
begin
  // переопределение оператора сравнения
  result:= CompareMem(@mac1, @mac2, sizeof(TMacAddress));
end;
 
function TMacAddress.get_as_text: string;
begin
  Result:= Format('%.2X:%.2X:%.2X:%.2X:%.2X:%.2X', [A0, A1, A2, A3, A4, A5]);
end;
 
function TMacAddress.is_zero: boolean;
begin
  var temp:= 0;
  for var x in self.Bytes do
    inc(temp, x);
  result:= temp = 0;
end;
 
procedure TMacAddress.set_as_text(const text: string);
const
  ERROR_FMT = 'Ошибка преобразования в MAC-адрес строки "%".';
begin
  // преобразование строки вида ХХ:ХХ:ХХ:ХХ:ХХ:ХХ в мас-адрес
  // числа - только шестнадцатеричные и без префикса/суффикса
  var sda:= SplitString(Trim(text), DELIMS);
  if length(sda) <> 6
    then raise EConvertError.CreateFmt(ERROR_FMT, [text]);
 
  var temp: TMacAddr48;
  var part: int32;
  for var idx:= 0 to 5 do
    if TryStrToInt('$' + sda[idx], part) and BetweenInt(part, 0, $FF)
      then temp[idx]:= part
      else raise EConvertError.CreateFmt(ERROR_FMT, [text]);
 
  self.Bytes:= temp;
end;
 
class function TMacAddress.validate(const text: string): boolean;
begin
  // проверка мас-адрес-строки на валидность
  // числа - только шестнадцатеричные и без префикса/суффикса
  var sda:= SplitString(Trim(text), DELIMS);
  if length(sda) <> 6
    then exit(false);
 
  var part: int32;
  for var idx:= 0 to 5 do
    if not TryStrToInt('$' + sda[idx], part) and BetweenInt(part, 0, $FF)
      then exit(false);
 
  result:= true;
end;
 
{$ENDREGION}
 
{$REGION 'TIpAddress_v4'}
{ TIpAddress_v4 }
 
class operator TIpAddress_v4.Equal(const ip1, ip2: TIpAddress_v4): Boolean;
begin
  // переопределение оператора сравнения
  result:= CompareMem(@ip1, @ip2, sizeof(TIpAddress_v4));
end;
 
function TIpAddress_v4.get_as_text: string;
begin
  Result:= Format('%d.%d.%d.%d', [B0, B1, B2, B3]);
end;
 
function TIpAddress_v4.get_subnet_class: TIPv4SubnetClass;
begin
  {$REGION 'класс подсети ( https://ru.wikipedia.org/wiki/IPv4 )'}
  { Класс А: 0.XXX.XXX.XXX — 127.XXX.XXX.XXX
    Первый бит адреса равен нулю, таким образом, класс А занимает половину всего адресного пространства.
    Адрес сети занимает 7 бит, адрес узла — 24 бита, следовательно класс A содержит 128 подсетей по 16 777 216 адресов в каждой.
    Например, подсеть 10.0.0.0 (класса А, содержит более 16,7 млн адресов от 10.0.0.0 по 10.255.255.255).
    По умолчанию зарезервирована, не маршрутизируется в интернете и используется для построения локальных и корпоративных сетей.
 
    Класс B: 128.0.XXX.XXX — 191.255.XXX.XXX
    Адрес начинается с битов 1,0, таким образом, класс B занимает четверть всего адресного пространства.
    Адрес сети занимает 14 бит, адрес узла — 16, следовательно класс B содержит 16 384 подсетей по 65 536 адресов в каждой
    Например, сеть 169.254.X.X класса B с 65536 адресами. Зарезервирована для «канальных» адресов.
 
    Класс C: 192.0.0.XXX — 223.255.255.XXX
    Адрес начинается с битов 1,1,0, таким образом, класс C занимает 1/8 адресного пространства.
    Адрес сети занимает 21 бит, адрес узла — 8 бит, следовательно класс C содержит 2 097 152 сетей по 256 адресов в каждой.
    Например, сеть 192.0.2.X имеет адреса с 192.0.2.0 по 192.0.2.255, зарезервирована для примеров в документации.
    В 1990 году в RFC 1166 (англ.) описаны ещё два класса.
 
    Класс D: 224.XXX.XXX.XXX — 239.XXX.XXX.XXX
    Адрес начинается с битов 1,1,1,0. Класс D занимает 1/16 адресного пространства. Используется для многоадресной рассылки.
 
    Класс Е: 240.XXX.XXX.XXX — 255.XXX.XXX.XXX.
    Адрес начинается с битов 1,1,1,1. Такие адреса запрещены. Зарезервировано для использования в будущем.
  }
  {$ENDREGION}
 
  case Self.B0 of
      0..127: result:= SUBNET_CLASS_A;
    128..191: result:= SUBNET_CLASS_B;
    192..223: result:= SUBNET_CLASS_C;
    224..239: result:= SUBNET_CLASS_D;
  else        result:= SUBNET_CLASS_E;
  end; // case
end;
 
function TIpAddress_v4.same_subnet(const ip: TIpAddress_v4): Boolean;
const
  // ширина (в битах) поля узлов в зависимости от класса подсети
  // https://ru.wikipedia.org/wiki/IPv4
  HOST_WIDTH:   array[TIPv4SubnetClass] of Byte = (24, 16, 8, 4, 4); // номер хоста - это СТАРШИЕ биты 4-байтного IP-адреса
  SUBNET_WIDTH: array[TIPv4SubnetClass] of Byte = (8, 16, 24, 28, 28); // ширина поля подсети - это МЛАДШИЕ биты 4-байтного IP-адреса
begin
  {$REGION 'проверка на принадлежность адреса той же подсети, что и сам  (+03 мар 2021)'}
  var c1:= Self.subnet_class;
  var c2:= ip.subnet_class;
  if c1 <> c2
    then exit(false);
  {$ENDREGION}
 
  // если классы совпали, проверяю равенство полей подсетей
  result:= BitCut32(Self.Value, SUBNET_WIDTH[c1]) = BitCut32(ip.Value, SUBNET_WIDTH[c2]);
end;
 
procedure TIpAddress_v4.set_as_text(const text: string);
const
  ERROR_FMT = 'Ошибка преобразования в IPv4-адрес строки "%".';
begin
  // преобразование строки вида a.b.c.d в IPv4-адрес
  // числа - десятичные, шестнадцатеричные с префиксом ($, 0x),
  // суффиксом (h), восьмеричные (с префиксом 0).
  var sda:= SplitString(Trim(text), DELIMS);
  if length(sda) <> 4
    then raise EConvertError.CreateFmt(ERROR_FMT, [text]);
 
  var temp: TIPv4;
  var part: int32;
  for var idx:= 0 to 3 do
    if TryStrToIntEx(sda[idx], part) and BetweenInt(part, 0, $FF)
      then temp[idx]:= part
      else raise EConvertError.CreateFmt(ERROR_FMT, [text]);
 
  self.Bytes:= temp;
end;
 
class function TIpAddress_v4.validate(const text: string): boolean;
begin
  // проверка IP-адрес-строки на валидность
  // числа - десятичные, шестнадцатеричные с префиксом ($, 0x),
  // суффиксом (h), восьмеричные (с префиксом 0).
  var sda:= SplitString(Trim(text), DELIMS);
  if length(sda) <> 4
    then exit(false);
 
  var part: int32;
  for var idx:= 0 to 3 do
    if not TryStrToIntEx(sda[idx], part) and BetweenInt(part, 0, $FF)
      then exit(false);
 
  result:= true;
end;
 
{$ENDREGION}
 
{$REGION 'TIpAddress_v6'}
procedure TIpAddress_v4.copy_from(const addr: pointer);
begin
  // копирование данных в структуру
  move(pbyte(addr)^, self, sizeof(self));
end;
 
{ TIpAddress_v6 }
 
function TIpAddress_v6.get_as_text: string;
begin
  result:= Format('%.4X:%.4X:%.4X:%.4X:%.4X:%.4X:%.4X:%.4X%%d',
                 [Prefix.word0, Prefix.word1, Prefix.word2, Prefix.word3,
                  IID.word0, IID.word1, IID.word2, IID.word3, Suffix]);
end;
 
procedure TIpAddress_v6.copy_from(const addr: pointer);
begin
  // копирование данных в структуру
  move(pbyte(addr)^, self, sizeof(self));
end;
 
{$ENDREGION}
 
{$REGION 'сервисные функции'}
function inet_addr(const ws: string): DWORD;
var
  s: AnsiString;
begin
  s:= AnsiString(ws);
  Result:= WinSock.inet_addr(PAnsiChar(s));
end;
 
function inet_ntoa(inaddr: TInAddr): string;
var
  buf: pAnsiChar;
begin
  buf:= WinSock.inet_ntoa(inaddr);
  Result:= string(AnsiString(buf));
end;
 
function GetHostByName(const wname: string): PHostEnt;
var
  s: AnsiString;
begin
  s:= AnsiString(wname);
  Result:= WinSock.GetHostByName(PAnsiChar(s));
end;
 
function GetHostName(var wname: string): Integer; // возвратит длину строки или -1 при ошибке
var
  pName: array[0..MAX_PATH - 1] of AnsiChar;
begin
  ZeroMemory(@pName, SizeOf(pName));
  Result:= WinSock.GetHostName(pName, SizeOf(pName));
  wname:= string(pName);
end;
 
function GetServByName(wname, wproto: string): PServEnt;
var
  name, proto: AnsiString;
begin
  name:= AnsiString(wname);
  proto:= AnsiString(wproto);
  Result:= WinSock.getservbyname(PAnsiChar(name), PAnsiChar(proto));
end;
 
function GetLocalIP: string;
var
  Buf: string;
begin
  Result:= '';
 
  if GetHostName(Buf) = 0
    then begin
           var P:= GetHostByName(Buf);
           if assigned(p)
             then Result:= iNet_ntoa(PInAddr(p^.h_addr_list^)^);
         end;
end;
 
//function IpToStr(const Addr: TInAddr): string;
//var
//  IP: TInAddr absolute Addr;
//begin
  {Result:= IntToStr(Addr and $FF) + '.' + IntToStr((Addr and $FF00) shr 8) + '.'
    + IntToStr((Addr and $FF0000) shr 16) + '.' +
    IntToStr((Addr and $FF000000) shr 24);}
  //with IP.S_un_b do Result:= Format('%d.%d.%d.%d', [Byte(s_b1), Byte(s_b2), Byte(s_b3), Byte(s_b4)]);
//  Result:= inet_ntoa(Addr);
//end;
 
function IpToStr(const dw: DWORD): string;
var
  IP: TInAddr absolute dw;
begin
  // адреса хранятся и передаются мл. байтов вперёд,
  // а старшим байтом вперёд (слева) - только отображаются как строка!
  // Смотри не перепутай, Кутузов!!!
  with IP.S_un_b do
    Result:= Format('%d.%d.%d.%d', [Byte(s_b1), Byte(s_b2), Byte(s_b3), Byte(s_b4)]);
end;
 
function TInAddrStructToText(A: TInAddr): string;
var
  sbytes: string;
begin
{ SunB = record
    s_b1, s_b2, s_b3, s_b4: u_char;
  end;
 
  SunW = record
    s_w1, s_w2: u_short;
  end;
 
  in_addr = record
    case integer of
      0: (S_un_b: SunB);
      1: (S_un_w: SunW);
      2: (S_addr: u_long);
  end;
  TInAddr = in_addr;
}
  sbytes:= inet_ntoa(A);
  Result:= Format('%d = 0x%.8X = (%s)', [A.S_addr, A.S_addr, sbytes]);
end;
 
function TryStrToIp(const s: string; out A: TInAddr): Boolean;
var
  dw: DWORD;
begin
  dw:= inet_addr(s);
  Result:= dw <> INADDR_NONE;
  if Result
    then A.S_addr:= dw;
end;
 
function WinSockErrorToString(err: Integer): string;
begin
// ---------- перевести на русский! ---------
// http://www.gamedev.ru/code/forum/?id=151700
// http://www.thalion.kiev.ua/idx.php/150/802/article/
  case err of
    WSAEINTR:                Result:= 'Interrupted system call';
    WSAEBADF:                Result:= 'Bad file number';
    WSAEACCES:               Result:= 'Permission denied';
    WSAEFAULT:               Result:= 'Bad address';
    WSAEINVAL:               Result:= 'Invalid argument';
    WSAEMFILE:               Result:= 'Too many open files';
    WSAEWOULDBLOCK:          Result:= 'Operation would block';
    WSAEINPROGRESS:          Result:= 'Operation now in progress';
    WSAEALREADY:             Result:= 'Operation already in progress';
    WSAENOTSOCK:             Result:= 'Socket operation on non-socket';
    WSAEDESTADDRREQ:         Result:= 'Destination address required';
    WSAEMSGSIZE:             Result:= 'Message too long';
    WSAEPROTOTYPE:           Result:= 'Protocol wrong type for socket';
    WSAENOPROTOOPT:          Result:= 'Protocol not available';
    WSAEPROTONOSUPPORT:      Result:= 'Protocol not supported';
    WSAESOCKTNOSUPPORT:      Result:= 'Socket type not supported';
    WSAEOPNOTSUPP:           Result:= 'Operation not supported on socket';
    WSAEPFNOSUPPORT:         Result:= 'Protocol family not supported';
    WSAEAFNOSUPPORT:         Result:= 'Address family not supported by protocol family';
    WSAEADDRINUSE:           Result:= 'Address already in use';
    WSAEADDRNOTAVAIL:        Result:= 'Can''t assign requested address';
    WSAENETDOWN:             Result:= 'Network is down';
    WSAENETUNREACH:          Result:= 'Network is unreachable';
    WSAENETRESET:            Result:= 'Network dropped connection on reset';
    WSAECONNABORTED:         Result:= 'Software caused connection abort';
    WSAECONNRESET:           Result:= 'Connection reset by peer';
    WSAENOBUFS:              Result:= 'No buffer space available';
    WSAEISCONN:              Result:= 'Socket is already connected';
    WSAENOTCONN:             Result:= 'Socket is not connected';
    WSAESHUTDOWN:            Result:= 'Can''t send after socket shutdown';
    WSAETOOMANYREFS:         Result:= 'Too many references: can''t splice';
    WSAETIMEDOUT:            Result:= 'Connection timed out';
    WSAECONNREFUSED:         Result:= 'Connection refused';
    WSAELOOP:                Result:= 'Too many levels of symbolic links';
    WSAENAMETOOLONG:         Result:= 'File name too long';
    WSAEHOSTDOWN:            Result:= 'Host is down';
    WSAEHOSTUNREACH:         Result:= 'No route to host';
    WSAENOTEMPTY:            Result:= 'Directory not empty';
    WSAEPROCLIM:             Result:= 'Too many processes';
    WSAEUSERS:               Result:= 'Too many users';
    WSAEDQUOT:               Result:= 'Disc quota exceeded';
    WSAESTALE:               Result:= 'Stale NFS file handle';
    WSAEREMOTE:              Result:= 'Too many levels of remote in path';
    WSASYSNOTREADY:          Result:= 'Network sub-system is unusable';
    WSAVERNOTSUPPORTED:      Result:= 'WinSock DLL cannot support this application';
    WSANOTINITIALISED:       Result:= 'WinSock not initialized';
    WSAHOST_NOT_FOUND:       Result:= 'Host not found';
    WSATRY_AGAIN:            Result:= 'Non-authoritative host not found';
    WSANO_RECOVERY:          Result:= 'Non-recoverable error';
    WSANO_DATA:              Result:= 'No Data';
  else
    Result:= 'Not a WinSock error';
    //Result:= Result + '.';
  end;
 
  result:= Format('%d: ', [err]) + result;
end;
 
procedure DNSLookup(Address: string; var HostName, IP: string);
var
  Host_Info: PHostEnt;
  IPBuffer:  Integer;
begin
  IPBuffer:= inet_addr(PChar(Address));
 
  if IPBuffer = Integer(INADDR_NONE)
    then begin
           Host_Info:= GetHostByName(PChar(Address));
 
           if Host_Info <> nil
             then begin
                    HostName:= Address;
                    move(Host_Info.h_addr_list^^, IPBuffer, 4);
                    IP:= IpToStr(IPBuffer);
                  end
             else begin
                    IP      := 'IP не найден.';
                    HostName:= 'Хост не найден.';
                  end;
         end
    else begin
           IP       := IpToStr(IPBuffer);
           HostName := 'Хост не найден.';
           Host_Info:= GetHostByAddr(@IPBuffer, 4, AF_INET);
 
           if Host_Info <> nil
             then HostName:= {StrPas}string(Host_Info.h_name);
         end;
end;
 
function Get_Inet_Addr(Addr: string): Integer;
var
  Host_Info: PHostEnt;
  iBuffer:   Integer;
begin
  iBuffer:= inet_addr(PChar(Addr));
 
  if iBuffer = Integer(INADDR_NONE)
    then begin
           Host_Info:= GetHostByName(PChar(Addr));
           if Host_Info <> nil
             then move(Host_Info.h_addr_list^^, iBuffer, 4);
         end;
 
  Result:= iBuffer;
end;
 
function RevertDW(const dw: DWORD): DWORD; inline;
type
  T4 = array[0..3] of Byte;
var
  X: T4 absolute dw;
  Y: T4 absolute Result;
  idx: Integer;
begin
  for idx:= 0 to 3 do
    Y[idx]:= X[3 - idx];
end;
 
function RevertW(const w: WORD): WORD; inline;
begin
  Result:= Word(w shl 8) or Word(w shr 8);
end;
{$ENDREGION}
 
end.
1
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,498
21.04.2023, 09:46
Цитата Сообщение от SeGun Посмотреть сообщение
Адрес явно String, в функции Cardinal объявлен - простите не догоняю.
Что не так? Нужно же из строки вида "192.168.0.0" получить IP-адрес? Вот функция разделяет строку на подстроки и пытается все 4 новые строки преобразовать в число и проверяет, попадают ли они в диапазон 0-255. Если всё нормально, то адрес собирается в 32 битной переменной "ip" и выдаётся наружу.
0
130 / 109 / 22
Регистрация: 23.05.2015
Сообщений: 736
21.04.2023, 10:03  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
Если всё нормально, то адрес собирается в 32 битной переменной "ip" и выдаётся наружу.
С этим понятно.
А как вызвать? Если указать только 1 параметр входную строку, то выдает ошибку (недостаточно параметров).
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,498
21.04.2023, 10:16
SeGun, сейчас кто-то прикалывается? Ты же неплохо разбираешься в дельфи и даже советы даёшь...

Вызывать так:
Delphi
1
2
3
4
5
6
7
8
9
procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  ip: cardinal;
begin
  s := '192.168.1.254';
  if ParseIpV4(s, ip) then Label1.Caption := IntToStr(ip)
                      else Label1.Caption := 'no IP';
end;
1
130 / 109 / 22
Регистрация: 23.05.2015
Сообщений: 736
21.04.2023, 10:23  [ТС]
А понятно, ты просто сказал, что туда ничего не нужно писать... вот вопрос и возник.
А по ip - по ходу, до вызова не инициализируется.
Теперь понял.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,498
21.04.2023, 10:24
Цитата Сообщение от SeGun Посмотреть сообщение
ip - по ходу, до вызова не инициализируется.
Да, в переменную ip не нужно ничего заранее писать (записывать).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.04.2023, 10:24

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

Как удалить символы ", [ и ] регулярным выражением?
Приветствую. Разбирающиеся в рег. выражениях, приведите пример, пожалуйста, как удалить символы &quot;, из строки. (двойная кавычка и...

Как выбрать конкретную ссылку регулярным выражением?
Есть рег выражение (https?:\/\/).* Допустим у меня 4 совпадения: https://greenelephant.com/standing-like-a-heron ...

Как объединить два массива с регулярным выражением?
В общем есть некая регулярка, в неё вносим два массива:1) массив выдающий ссылки с другого сайта (2) массив личных ссылок. Задача:заменить...

Как определить длину строки, вырезанной регулярным выражением?
Здравствуйте. Собственно вот вопрос, length не подходит...) var url = location.search; var regexr=/id=.*/ ; var cut =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru