IP-адреса чи ні?


25

Ваш мережевий інструмент сканування дратує вимогливість щодо введення даних і негайно виходить з ладу, якщо ви подаєте йому адресу IPv4, яка містить неправильні символи або неправильно відформатована.

IPv4-адреса - це 32-розрядна числова адреса, записана у вигляді чотирьох чисел, розділених періодами. Кожне число може бути від нуля до 255 .

Нам потрібно написати інструмент для попередньої перевірки введення, щоб уникнути цих збоїв, і наш конкретний інструмент є вибагливим: дійсний формат виглядатиме як a.b.c.dде, a, b, c і d:

  • Це може бути 0натуральне число або без нульових нулів .
  • Має бути від 0 до 255 (включно).
  • Якщо НЕ містять спеціальні символи , такі як +, -, ,та інші.
  • Має бути десятковим (базовим 10)

Введення : Рядок

Вихід : значення Truthy або Falsey (довільні значення також приймаються)

Випробування :

Input            |  Output  |  Reason
                 |          |
- 1.160.10.240   |  true    |
- 192.001.32.47  |  false   |  (leading zeros present)
- 1.2.3.         |  false   |  (only three digits)
- 1.2.3          |  false   |  (only three digits)
- 0.00.10.255    |  false   |  (leading zeros present)
- 1.2.$.4        |  false   |  (only three digits and a special symbol present)
- 255.160.0.34   |  true    |
- .1.1.1         |  false   |  (only three digits)
- 1..1.1.1       |  false   |  (more than three periods)
- 1.1.1.-0       |  false   |  (special symbol present)
- .1.1.+1        |  false   |  (special symbol present)
- 1 1 1 1        |  false   |  (no periods)
- 1              |  false   |  (only one digit)
- 10.300.4.0     |  false   |  (value over 255)
- 10.4F.10.99    |  false   |  (invalid characters)
- fruit loops    |  false   |  (umm...)
- 1.2.3.4.5      |  false   |  (too many periods/numbers)
- 0.0.0.0        |  true    |
- 0.0 0.0.       |  false   |  (periods misplaced)
- 1.23..4        |  false   |  (a typo of 1.2.3.4)
- 1:1:1:1:1:1:1:1|  false   |  (an IPv6 address, not IPv4)

Це , тому виграє найменше байтів!

Примітка для користувачів - якщо ви хочете додати ще кілька тестових випадків, вас вітають (запропонувавши редагувати). Але будь ласка, переконайтеся, що тестові справи не повторюються! Спасибі


10
Пропонуйте testcases: 1.1.1.1.1, 1.1.1.1., .1.1.1, 1..1.1, 1..1.1.1, 1.1.1.0, 1.1.1.-0, 1.1.1.+1, 1.1.1.1E1, 1.1.1.256, 1.1.1.0x1, 255.255.255.255, 0.0.0.0, 'or 1=1--, <empty string>, 1 1 1 1, 1,1,1,1.
tsh

5
Запропонуйте додати тестові випадки "1.2.3.4.5" (щоб виключити занадто довгі IP-адреси) та "999.0.0.0" (щоб виключити занадто великі IP-адреси).
Тригернометрія

5
Можливо, трохи прискіпливий, але вам, мабуть, слід посилатися на "IPv4 адреси", а не на "IP адреси" - або, принаймні, десь зазначити, що ви просто маєте на увазі IPv4 адреси - інакше 1234: 5678 :: 1 має бути дійсною IP-адресою (тоді як з опису видно, що це не призначено :)
psmears

3
@Criggie Передумова не є фактично перевіряти всі реальні правила IP4 (наприклад, ті, які ви згадали), це забезпечити, щоб рядок вводу не зламав якийсь інший (імовірно, погано написаний) додаток, який дозволяє вводити лише в дуже конкретній формі . Крім того, ми не збираємось змінювати правила виклику, на які вже є 30+ відповідей.
BradC

2
@Criggie Варто зазначити, що RFC заявляє, що "адреси мають фіксовану довжину чотирьох октетів". Я думаю, що випадкові випадки, на які ви посилаєтесь, є більш спеціалізованими, ніж ця проблема.
Пік

Відповіді:


26

X86_64 код машини: 18 16 байт

Редагувати: Ця відповідь не дуже працює, як

  1. Я використовую inet_ptonзі стандартних бібліотек С, це означає, що мені потрібен зовнішній вигляд. Я не включав зовнішній вигляд у свій байт.
  2. Я використовував червону зону як результат для фактичної адреси, але називав функцію, яка також могла використовувати червону зону. На щастя, це не на моїй машині, але деяка типова збірка стандартної бібліотеки може використовувати її, що може спричинити невизначеність поведінки.

І так, вся справа в значній мірі виконується вже написаною функцією

У всякому разі, ось що я отримав: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Збірка:

section .text
    extern inet_pton
    global ipIsValid

ipIsValid:
    mov rsi, rdi
    ;mov rdi, 2 ; change to 10 for ipv6
    push 2
    pop rdi ; thank you peter
    lea rdx, [rsp - 128]
    jmp inet_pton

Пояснення:

Погляньте inet_pton(3). Він бере рядкову IP-адресу і поміщає її в буфер, з яким можна використовувати struct sockaddr. Це потребує 3 аргументів: сімейство адрес ( AF_INET(ipv4), 2 або AF_INET6(ipv6), 10), рядок ip адреси та вказівник на вихід. Він повертає 1 за успіхом, 0 для невірної адреси або -1 для, коли сім'я адрес не є AF_INETабо AF_INET6(що ніколи не відбудеться, тому що я передаю їй постійну).

Тому я просто переміщую рядок до регістра для другого аргументу, встановлюю перший реєстр на 2, а третій реєстр встановлюю в червону зону (128 байт нижче вказівника стека), оскільки мене не хвилює результат. Тоді я можу просто jmpдо inet_ptonі нехай , що повернення прямо до абонента!

Я запустив цю швидку програму тестування, щоб перевірити ваші справи:

#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/ip.h>

extern int ipIsValid(char *);

int main(){
    char *addresses[] = {
        "1.160.10.240",
        "192.001.32.47",
        "1.2.3.",
        "1.2.3",
        "0.00.10.255",
        "1.2.$.4",
        "255.160.0.34",
        ".1.1.1",
        "1..1.1.1",
        "1.1.1.-0",
        ".1.1.+1",
        "1 1 1 1",
        "1",
        "10.300.4.0",
        "10.4F.10.99",
        "fruit loops",
        "1.2.3.4.5",
        NULL
    };

    for(size_t i = 0; addresses[i] != NULL; ++i){
        printf("Address %s:\t%s\n", addresses[i],
            ipIsValid(addresses[i]) ? "true" : "false");
    }
    return 0;
}

Зберіть nasm -felf64 assembly.asm, компілюйте gcc -no-pie test.c assembly.o, і ви отримаєте:

Address 1.160.10.240:   true
Address 192.001.32.47:  false
Address 1.2.3.: false
Address 1.2.3:  false
Address 0.00.10.255:    false
Address 1.2.$.4:    false
Address 255.160.0.34:   true
Address .1.1.1: false
Address 1..1.1.1:   false
Address 1.1.1.-0:   false
Address .1.1.+1:    false
Address 1 1 1 1:    false
Address 1:  false
Address 10.300.4.0: false
Address 10.4F.10.99:    false
Address fruit loops:    false
Address 1.2.3.4.5:  false

Я міг би зробити це набагато меншим, якби абонент повинен був перейти AF_INETабо AF_INET6перейти до функції


4
Мені подобається, що ти зробив це в асм. А те, що ви пояснили це тим, хто цього не розуміє (як і тестовий код), ще краще. Що не означає, що я міг би це зробити в асм; Занадто багато років минуло, але я пам'ятаю достатньо, щоб точно зрозуміти, що говорить (і, отже, процес) вашого пояснення. Хороша робота.
Прифтан

4
e9 00 00 00 00є а jmp near $+5, а не jmp inet_pton. Якщо ви надаєте опкод, вам слід включити inet_ptonчастину, що включає , а не
пустувати


3
ви повинні включити зовнішній вигляд у назву відповіді, оскільки програма вимагає цього, і він доступний не на всіх платформах.
qwr

1
"mov rdi, 2" може бути "push 2 / pop rdi" на -2 байти. Зауважте також, що розбирання неправильне або код неправильний. Це або "mov edi" (не rdi), або префікс відсутній.
peter ferrie

13

Java (JDK) , 63 байти

s->("."+s).matches("(\\.(25[0-5]|(2[0-4]|1\\d|[1-9])?\\d)){4}")

Спробуйте в Інтернеті!

Кредити


Ви забули прибрати задні двокрапки. ;) І я можу перевірити, чи працює він у всіх тестових випадках, включаючи коментарі. Побачу, чи побачу я якісь речі для гольфу.
Кевін Кройсейсен

3
Помилка.1.2.3.4
l4m2

Чи дозволено використовувати булеві, коли explictly вимагають 0/1?
l4m2

1
@ l4m2 Первісне запитання було "Дійсне / Недійсне". Тому я припускаю, що будь-яке значення truthy / falsey є прийнятним тут.
Кевін Кройсейсен

Output: 0 or 1а у Java немає автоматичного bool-> int
l4m2

12

JavaScript (Node.js) , 43 байти

x=>x.split`.`.map(t=>[t&255]==t&&[])==`,,,`

Спробуйте в Інтернеті!

JavaScript (Node.js) , 46 байт

x=>x.split`.`.every(t=>k--&&[t&255]==t,k=4)*!k

Спробуйте в Інтернеті!

використовував частину Арнальда

JavaScript (Node.js) , 54 53 51 байт

x=>x.split`.`.every(t=>k--*0+t<256&[~~t]==t,k=4)*!k

Спробуйте в Інтернеті!

-2B для 0+t<256, -1B від Патріка Стефансена, + 1B для уникнення введення1.1.1.1e-80

Рішення RegExp 58 54 байти

s=>/^((2(?!5?[6-9])|1|(?!0\d))\d\d?\.?\b){4}$/.test(s)

Подякуйте Deadcode за 3 байти


Я додав кілька тестових випадків!
rv7


1
@KevinCruijssen 0.0.0.0тут справжній. Тільки чому тут введення SQL?
l4m2

Ну зачекайте, я неправильно трактую речення в описі виклику. 0.0.0.0справді є правдою. Це буде гольф моя відповідь, а .. (? А що ви маєте на увазі під SQL ін'єкції: S посилання на TIO з тестовими ВСІХ.)
Kevin Cruijssen

1
@ l4m2 Я додав його, оскільки нам потрібні кілька тестів, які навіть не схожі на IP-адресу.
tsh

11

PHP , 39 36 байт

<?=+!!filter_var($argv[1],275,5**9);

Спробуйте в Інтернеті!

275 нагадує константу FILTER_VALIDATE_IP

5 ** 9 використовується замість постійної FILTER_FLAG_IPV4. Цього достатньо, тому що 5**9 & FILTER_FLAG_IPV4truthy - це саме те, що PHP робить на задньому плані, як зазначив Бенуа Еснард.

Тут filter_varповертається перший аргумент, якщо це дійсна IPv4-адреса, або хибна, якщо ні. З +!!, ми виробляємо результат, необхідний завданням.


3
Тут використовується 5**9замість 1048576збереження 3 байтів: PHP використовує &для тестування прапорців IPv4 / IPv6 , тому будь-яке число між 1048576 та 2097151 є дійсним.
Бенуа Еснард

Я відповідаю вашій відповіді за те, що ви (в основному) мою відповідь: codegolf.stackexchange.com/a/174470/14732, яка написана в 2018-10-22 09: 17: 34UTC, тоді як ваша була написана 2018-10-22 09: 21: 55UTC. Навіть якщо я скасую 1-байтну оптимізацію, надану @BenoitEsnard, моя відповідь у функціональності точно така ж, як і ваша.
Ісмаїл Мігель

2
Мені потрібно вибачитися, я не побачив вашої відповіді, хоча на той момент, коли я її складав, в PHP на це питання не було представлень (як ви сказали, різниця у часі становить менше п’яти хвилин).
октюполь

Я знаю, і це розумію. Я твій тільки зараз помітив. Я можу відкотити шахту, а ви зберігаєте оптимізацію. Але я не знаю, чи робить це відповідь достатньо відмінним від інших.
Ісмаїл Мігель

17
@IsmaelMiguel Я не став би когось за це, якщо правдоподібний твій не був там, коли вони почалися. З 5-хвилинною різницею це не тільки правдоподібно, це майже напевно так, що очевидно навіть без того, що автор так сказав сам.
Дункан X Сімпсон

11

PHP, 36 байт

echo(ip2long($argv[1])===false?0:1);

ip2long- добре відома вбудована функція .



Це, здається, використовує некодировані функції, наявні в новіших версіях (я припускаю, що це з PHP7 +). Майте на увазі, що для PHP 4 і 5 це дійсно приймає неповні IP-адреси.
Ісмаїл Мігель



1
Це дасть успіх, якщо ви будете годувати його будь-яким цілим числом, таким як 1, 2 і т. Д. Не думайте, що це повинно. А також, якщо ви будете годувати нею як 100.100.100
nl-x

10

Perl 6 , 22 21 20 байт

-1 байт завдяки Філу Х.

{?/^@(^256)**4%\.$/}

Спробуйте в Інтернеті!

Пояснення

{                  }  # Anonymous Block
  /               /   # Regex match
   ^             $    # Anchor to start/end
    @(    )           # Interpolate
      ^256            #   range 0..255,
                      #   effectively like (0|1|2|...|255)
           **4        # Repeated four times
              %\.     # Separated by dot
 ?                    # Convert match result to Bool

3
Людина, мені потрібно витратити більше часу на з'ясування регексів Perl 6. У мене не було жодного %модифікатора. Цікаво, чи намагається перевірити всі 256**4можливості?
Джо Кінг

1
Замість цього <{^256}>ви можете просто перетворити діапазон у масив @(^256)для -1 char TIO . Змінюючи блок коду на масив, він також стає надзвичайно швидшим (0,4s замість> 30).
Phil H

@PhilH Класно, дякую. Я намагався, $(^256)але тепер я розумію, чому це не вийшло.
nwellnhof

9

05AB1E , 26 24 23 22 23 байт

'.¡©g4Q₅Ý®å`®1šDïþJsJQP

-1 байт завдяки @Emigna .
+1 байт для тестового випадку виправлення помилок, що 1.1.1.1E1неправильно повертає правдивий результат.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

'.¡              '# Split the (implicit) input by "."
   ©              # Save it in the register (without popping)
    g4Q           # Check that there are exactly 4 numbers
    ₅Ý®å          # Check for each of the numbers that they are in the range [0,255],
        `         # and push the result for each number separated onto the stack
    ®1šDïþJsJQ    # Check that each number does NOT start with a "0" (excluding 0s itself),
                  # and that they consist of digits only
              P   # Check if all values on the stack are truthy (and output implicitly)

1
Ви повинні мати можливість використовувати Āзамість<d
Emigna

@MagicOctopusUrn Боюся , він не для 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, і 0.00.10.255. (PS: Я виправив 1.1.1.1E1, додавши þдо чека приєднання і рівності.)
Кевін Круїйсен

Досить справедливо, зрозумів, що я щось пропустив.
Чарівна восьминога урна

@MagicOctopusUrn Основна проблема полягає в тому, щоб 05AB1E бачив числа з провідними 0, рівними числам без, навіть як рядки. Саме тому я використовую DïþJsJQчек , де ïкинути його в ціле , щоб видалити провідні 0s, і þтільки листя цифри видалення речі , як E, -і т.д. :) для тесту 0.00.10.255, так 00010255і 0010255будуть рівні.
Кевін Круїйсен

Так, я пережив ту саму нісенітницю, перевернення всіх чисел спрацювало досить добре, окрім тих випадків. Цікаво, коли функції, корисні для одних проблем, стають майже помилковими для інших.
Чарівна урвиця

6

PowerShell, 59 51 49 байт

-8 байт, дякую @AdmBorkBork

-2 байти, trueабо falseдозволено автором

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}

Тестовий сценарій:

$f = {

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}

}

@(
    ,("1.160.10.240" , $true)
    ,("192.001.32.47" , $false)
    ,("1.2.3." , $false)
    ,("1.2.3" , $false)
    ,("0.00.10.255" , $false)
    ,("192.168.1.1" , $true)
    ,("1.2.$.4" , $false)
    ,("255.160.0.34" , $true)
    ,(".1.1.1" , $false)
    ,("1..1.1.1" , $false)
    ,("1.1.1.-0" , $false)
    ,("1.1.1.+1" , $false)
    ,("1 1 1 1" , $false)
    ,("1"            ,$false)
    ,("10.300.4.0"   ,$false)
    ,("10.4F.10.99"  ,$false)
    ,("fruit loops"  ,$false)
    ,("1.2.3.4.5"    ,$false)

) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result : $s"
}

Вихід:

True: True : 1.160.10.240
True: False : 192.001.32.47
True: False : 1.2.3.
True: False : 1.2.3
True: False : 0.00.10.255
True: True : 192.168.1.1
True: False : 1.2.$.4
True: True : 255.160.0.34
True: False : .1.1.1
True: False : 1..1.1.1
True: False : 1.1.1.-0
True: False : 1.1.1.+1
True: False : 1 1 1 1
True: False : 1
True: False : 10.300.4.0
True: False : 10.4F.10.99
True: False : fruit loops
True: False : 1.2.3.4.5

Пояснення:

Сценарій намагається проаналізувати рядок аргументу, побудувати об’єкт .NET, IPAddress .

  • return, $trueякщо objectстворено, і рядок аргументу дорівнює рядковому поданню object(нормалізована адреса за object.toString())
  • повернути $falseінакше

PowerShell, 59 56 54 байти, не використовуйте альтернативу .NET lib

-3 байти, trueабо falseдозволено автором

-2 байти, завдяки @ Deadcode за прохолодний regexp.

".$args"-match'^(\.(2(?!5?[6-9])|1|(?!0\B))\d\d?){4}$'

Спробуйте в Інтернеті!

Дякуємо @ Олів'є Грегоару за оригінальний регулярний вираз.


1
Вам не потрібно дзвонити, |% t*gоскільки PowerShell автоматично передає праву частину -eqу вигляді рядка, оскільки ліва частина - це рядок. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork

Ви можете вирізати 2 байти з версії "не використовувати .NET lib", використовуючи мій регулярний вираз (адаптований до трюку вставки, який, звичайно, не може бути у моїй версії, оскільки це чистий регулярний вираз): tio.run/…
Deadcode

5

C (gcc) / POSIX, 26 байт

f(s){s=inet_pton(2,s,&s);}

Спробуйте в Інтернеті!

Працює як 64-бітний код у TIO, але, ймовірно, вимагає цього sizeof(int) == sizeof(char*)на інших платформах.


@TobySpeight Так, якщо ви перебуваєте на x86, ви, мабуть, спробуйте в 32-бітному режимі ( -m32).
nwellnhof

Я змусив його працювати, передаючи sяк char*(немає доступу до системи ILP32 тут), і так, я змішувався inet_aton().
Toby Speight

5

PHP 7 і більше, 37 35 32 байти

Для цього використовується вбудована функція filter_var, щоб перевірити, що це адреса IPv4 .

Щоб він працював, вам потрібно передати ключ iнад GET-запитом.

<?=filter_var($_GET[i],275,5**9);

Не виведе нічого (для falsyрезультату) або IP (для truthyрезультату), залежно від результату.

Ви можете спробувати це на: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Для цього безпосередньо використовуються такі значення:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (який має необхідний біт як "1" для 1048576)

Дякую Бенуа Еснару за цю пораду, яка врятувала мене 1 байт!

Дякую Титу за те, що нагадав мені про зміни у виклику.


Я розглядав використання функції ip2long, але вона працює з неповними IP-адресами.

У цьому виклику неповні адреси IPv4 вважаються недійсними.

Якби вони були дозволені, це буде остаточний код (лише для PHP 5.2.10):

<?=ip2long($_GET[i]);

Наразі в документації не очевидно, що це припинить роботу (коли буде передано неповний ip) з новішими версіями PHP.

Після тестування підтвердив, що це було так.

Дякуємо nwellnhof за пораду!


Використання тут 5**9замість 1<<20одного байту: PHP використовує &для тестування прапорців IPv4 / IPv6 , тому будь-яке число між 1048576 та 2097151 є дійсним.
Бенуа Еснард

У новіших версіях PHP ip2longне допускаються неповні адреси.
nwellnhof

@BenoitEsnard Дякую! Я додав це у відповідь
Ісмаель Мігель

@nwellnhof Після тестування я підтверджую, що це так. Однак я не вважаю, що це корисна ідея, оскільки це не є явно задокументованим.
Ісмаїл Мігель

+!!не потрібно; В даний час ОП приймає довільні значення "trutty".
Тит

5

Пітон 3: 81 78 70 69 66 байт

['%d.%d.%d.%d'%(*x.to_bytes(4,'big'),)for x in range(16**8)].count

Переведіть петлю на всі можливі адреси IPv4, отримайте подання рядка та порівняйте його з вхідним. Це ... пробігає час.

EDIT: Видалено 3 байти шляхом переходу з повної програми на анонімну функцію.

EDIT2: Видалено 8 байтів за допомогою xnor

EDIT3: Видалено 1 байт за допомогою розпакованої карти замість розуміння списку

EDIT4: Видалено 3 байти за допомогою розуміння списку замість ipaddressмодуля


2
Я думаю, що ваша анонімна функція просто може бути [str(ip_address(x))for x in range(256**4)].count. Також 256**4може бути 16**8.
xnor

5

C # (Visual C # Interactive Compiler) , 84 79 65 байт

s=>s.Split('.').Sum(t=>byte.TryParse(t,out var b)&t==b+""?1:5)==4

Спробуйте в Інтернеті!

-5 та -14 байт збережено завдяки @dana!

# C # (Visual C # Interactive Compiler) , 61 байт

s=>s.Count(c=>c==46)==3&IPAddress.TryParse(s,out IPAddress i)

Спробуйте в Інтернеті!

Це незавершена робота. Використання коду System.Net(якщо ви порахуєте його +17 байт). якщо вам цікаво, чому я рахую і розбираю:

Обмеження методом IPAddress.TryParse полягає в тому, що він перевіряє, чи може рядок може бути перетворений на IP-адресу, таким чином, якщо їй надається значення рядка типу "5", він вважає це "0,0.0.5".

джерело

Як заявив @milk у коментарі, він дійсно не вдасться до провідних нулів. Отже, 61 байт не працює.


1
@dana чудово. Чудово зроблено! Ще чотири, і він обіграє 61 байт рішення!
aloisdg повідомляє Відновити Моніку

4

Python 2 , 85 82 81 байт

-1 байт завдяки Kevin Cruijssen

from ipaddress import*
I=input()
try:r=I==str(IPv4Address(I))
except:r=0
print~~r

Спробуйте в Інтернеті!

113 байт відповідь видаляється, як це не вдалося1.1.1.1e-80


1
Ви можете грати в гольф print 1*rз print~~r. +1, однак, як здається, працює для всіх можливих тестових випадків, запропонованих до цих пір . PS: Ваша відповідь на 113 байтів не вдається 1.1.1.1e-80.
Кевін Кройсейсен

@KevinCruijssen Дякую! Не думали про таке позначення чисел
Dead Possum

Це не ipaddressмодуль Python 3?
Farhan.K

@ Farhan.K Данно, але це працює в TIO
Dead Possum

4

Japt, 17 15 байт

q.
ʶ4«Uk#ÿòs)Ê

Спробуйте або запустіть усі тестові випадки або перевірте додаткові тестові випадки з коментарів на виклики


Пояснення

Ми розділимо на масив на ., перевіримо, чи довжина цього масиву дорівнює 4І, що довжина, коли всі елементи в діапазоні ["0","255"]видаляються з нього, є falsey ( 0).

                 :Implicit input of string U
q.               :Split on "."
\n               :Reassign resulting array to U
Ê                :Length of U
 ¶4              :Equals 4?
   «             :&&!
    Uk           :Remove from U
      #ÿ         :  255
        ò        :  Range [0,255]
         s       :  Convert each to a string
          )      :End removal
           Ê     :Length of resulting array

Гарна відповідь. Також перевірено для всіх запропонованих досі тестових випадків . Цікаво бачити це пояснення.
Кевін Кройсейсен

2
@KevinCruijssen, пояснення додано. Дякуємо за додаткові тестові випадки.
Кудлатий

3

Математика, 39 31 байт

Оригінальна версія:

¬FailureQ[Interpreter["IPAddress"][#]]&

Модифікована версія (дякую Міші Лаврову)

 AtomQ@*Interpreter["IPAddress"]

який повертається, Trueякщо вхід є дійсною IP-адресою ( спробуйте ).

Якщо ви наполягаєте на отриманні 1та 0замість цього, знадобиться додаткові 7 байт:

Boole/@AtomQ@*Interpreter["IPAddress"]

Оскільки Interpreter["IPAddress"]повертає рядок для дійсного введення, а також якийсь складний об'єкт відмови для недійсного введення, ми можемо перевірити дійсні входи з AtomQ[Interpreter["IPAddress"][#]]&, які можна додатково скоротити до складу функції AtomQ@*Interpreter["IPAddress"]. Спробуйте в Інтернеті!
Міша Лавров

Помилка такої адреси IPv6, як 2001:0db8:85a3:0000:0000:8a2e:0370:7334.
lirtosiast


3

Python 2, 93 89 67 53 байт

[i==`int(i)&255`for i in input().split('.')]!=[1]*4>_

Спробуйте в Інтернеті!

Дякуємо Деннісу за те, що поголив ще 14 байт на внутрішніх порівняннях та вихідних кодах.

Особлива подяка Джонатану Аллану за гоління 22 байтів та логічне виправлення! Пескі спробувати / крім того, що вже!

Завдяки Джо Кінгу, якщо правильно відформатовані рядки замість сирих байтів, слід відкинути 4 байти.


Ваш чек можна пограти в гольф i==`int(i)&255` . Також ви можете виправити помилку [...]!=[1]*4>_, оскільки ви все одно використовуєте вихідні коди. Спробуйте в Інтернеті!
Денніс

@Dennis Я не розумію, що >_робить. Хоч битовий і досить геніальний ... Мені не вдалося поєднати їх самі.
TemporalWolf

2
Якщо !=повертається помилковим, коротке замикання Python і нічого не відбувається; перекладач виходить нормально. Якщо він повертає True, >_піднімає NameError, оскільки змінна _не визначена.
Денніс

Цифри я ланцюжок порівнянь у своїй відповіді, а потім пропускаю очевидний результат у вашому коментарі. Дякую за пояснення.
TemporalWolf

3

sfk , 176 байт

* спочатку був Bash + SFK, але з тих пір TIO додав належну обгортку SFK

xex -i "_[lstart][1.3 digits].[1.3 digits].[1.3 digits].[1.3 digits][lend]_[part2]\n[part4]\n[part6]\n[part8]_" +xed _[lstart]0[digit]_999_ +hex +linelen +filt -+1 -+2 +linelen

Спробуйте в Інтернеті!


Спочатку перевіримо роздруківку помилок, щоб nc [addr] 1 -w1скоротити цю?

@Rogem ncприймає провідні нулі, а також IPv6 адреси, тому мені все одно доведеться обробляти їх - і це все-таки швидше sfkвідповідь, ніж відповідь оболонки.
Οurous

3

Python3 Bash * 60

* Також інші снаряди. Будь-який, для якого тест на правду / хибність проходить код виходу з програми

read I
python3 -c "from ipaddress import*;IPv4Address('$I')"

Пояснення

Проблема з чистими рішеннями Python полягає в тому, що збій програми вважається невизначеним. Ми могли б використати "багато" коду, щоб перетворити виняток у відповідне значення "truthy / fasly". Однак в якийсь момент інтерпретатор Python обробляє цей невловимий виняток і повертає ненульовий код виходу. За низькою та низькою ціною зміни мов улюблену оболонку Unix ми можемо заощадити зовсім небагато коду!

Звичайно, це є вразливим до атак ін'єкцій ... Такі матеріали, як така, 1.1.1.1'); print('Doing Something Evilє неяскравою загрозою!


( Пояснення це (не пояснення ).)
Пітер Мортенсен

@PeterMortensen Yikes. Він навіть був підкреслений червоним кольором. Мій браузер намагався врятувати мене, але я не хотів слухати. Дякуємо, що це зробили!
Сомпом

Повні програми дозволяється виводити через вихідні коди, тому це може бути 43 байти .
ბიმო

@BMO Цікаво. Дякуємо, що вказали на це! Я думаю, що проблема definiiton змінилася з "Truthy / Falsy" на можливість дозволити довільний вихід, оскільки я опублікував це, але я міг просто не помітити раніше :)
Sompom

3

Чистий регулярний вираз із ECMAScript, 41 байт

^((2(?!5?[6-9])|1|(?!0\B))\d\d?\.?\b){4}$

Спробуйте в Інтернеті!
Спробуйте його на regex101

Я думаю, що логіка в цьому регулярному виразі говорить сама за себе, тому я буду просто друкувати, але не коментувати:

^
(
    (
        2(?!5?[6-9])
    |
        1
    |
        (?!0\B)
    )
    \d\d?
    \.?\b
){4}
$

Це можна використовувати для гоління 2-х байт з наступних інших відповідей:

Ось альтернативна версія, яка дозволяє провідні нулі, але робить це послідовно (октети можуть бути представлені максимум 3 десятковими цифрами):

^((2(?!5?[6-9])|1|0?)\d\d?\.?\b){4}$

Або дозволити будь-яку кількість провідних нулів:

^(0*(2(?!5?[6-9])|1?)\d\d?\.?\b){4}$


1
\bі \B... це розумно!
маззи

1
@mazzy Так, ці двоє справді корисні! Я міг би (?!0\d)замість цього використати , але мені подобається \Bкраще!
Deadcode

Відповідь повноважень не коротшає з вашим регулярним показом. Мені шкода. Котирування потрібні для перетворення масиву в рядок. Спробуйте в Інтернеті!
маззи

1
\.?\bСпас мене байт як на мене відповідь теж, спасибі!
Ніл

1
Збережено 3 байти thx
l4m2

2

Червоний , 106 байт

func[s][if error? try[t: load s][return off]if 4 <> length? t[return off]s =
form as-ipv4 t/1 t/2 t/3 t/4]

Спробуйте в Інтернеті!

Повернення trueабоfalse

Пояснення:

f: func [ s ] [
    if error? try [                  ; checks if the execution of the next block result in an error
        t: load s                    ; loading a string separated by '.' gives a tuple   
    ] [                              ; each part of which must be in the range 0..255
        return off                   ; if there's an error, return 'false' 
    ]
    if 4 <> length? t [              ; if the tuple doesn't have exactly 4 parts
        return off                   ; return 'false'  
    ]
    s = form as-ipv4 t/1 t/2 t/3 t/4 ; is the input equal to its parts converted to an IP adress
]

2

Стакс , 14 байт

∞n·Θ3ª&JH‼∙*~Γ

Запустіть і налагоджуйте його

Розпакований, неозорений та прокоментований, це виглядає приблизно так.

VB      constant 256
r       [0 .. 255]
'|*     coerce and string-join with "|"; i.e. "0|1|2|3 ... 254|255"
:{      parenthesize to "(0|1|2|3 ... 254|255)"
]4*     make 4-length array of number pattern
.\.*    string join with "\\."; this forms the complete regex
|Q      is the input a complete match for the regex?

Виконати цей


Здивовано, дізнавшись, що ви зробили мову Stax! це працює добре.
rv7

Спасибі! Простір мов для гри в гольф напрочуд переповнений, і я не впевнений, що Stax може виправдати власне існування за своїми достоїнствами, але моя головна мета полягала лише в тому, щоб побачити, чи зможу я це зробити і, можливо, чогось навчитись. Це закінчилося веселіше, ніж очікувалося.
рекурсивна

2

Пітон 3, 109 93 байти

import re
lambda x:bool(re.match(r'^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(\.(?!$)|$)){4}$',x))

Пояснення

Кожен октет може бути 0 - 255:

  • починається з 25 і має 0-5 як останню цифру
  • Почніть з 2, має 0-4 як другу цифру і будь-яку цифру в кінці
  • починається з 1, а 00 - 99 як цифри відпочинку
  • має лише 2 цифри - 1-9 - перша і будь-яка цифра після цього
  • або просто одна цифра

Октет може закінчитися з (.) Або тільки кінець, з умовою , що він не може зробити так, негативний попередній (?!$)піклується про даний випадок

Завдяки @Zachary для виготовлення мені зрозуміти , що я можу відмовитися від простору (так як це код гольфу)
Дякую @DLosc для поліпшення і змушує мене усвідомити свою помилку, його було скориговано в даний час.


2
Деякі пояснення цьому можуть допомогти.
Нісса

x: re.match=> x:re.match; , x=> ,x, і ) is=> )isмає зберегти 3 байти. Крім того, у регулярному вираженні ви можете використовувати \dдля кожного виникнення [0-9], і [1]=> 1. Це здається чудовим першим повідомленням, хоча!
Zacharý

[1-9][0-9]|[0-9]може стати [1-9]\d|\d(за порадою Захарі), яким може стати [1-9]?\d. Крім того, замість тестування re.match(...)is not Noneви можете робити, bool(re.match(...))оскільки збігаються об'єкти, які є простіми та Noneфальсийними. :)
DLosc

Хм. Насправді це не вдається в тестовій справі 1.2.3.4.5(а також 1.2.3.4., що відсутня в офіційному списку тестових випадків), оскільки вона може відповідати періоду замість кінця рядка після четвертого числа.
DLosc


2

Вугілля деревне , 45 21 байт

I∧⁼№θ.³¬Φ⪪θ.¬№E²⁵⁶Iλι

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Редагувати. Збережено 24 байти, перенісши відповідь @ Shaggy's Japt. Пояснення:

    θ                   Input string
   №                    Count occurrences of
     .                  Literal `.`
  ⁼                     Equal to
      ³                 Literal 3
 ∧                      Logical And
       ¬                Logical Not
          θ             Input string
         ⪪              Split on
           .            Literal `.`
        Φ               Filter by
            ¬           Logical Not
               ²⁵⁶      Literal 256
              E         Map over implicit range
                   λ    Map value
                  I     Cast to string
             №          Count occurrences of
                    ι   Filter value
I                       Cast to string
                        Implicitly print

Помилки для тестових випадків з негативними цілими числами, як 123.-50.0.12або 1.1.1.-80. Все інше, здається, працює добре. Тож <256перевірка повинна бути in [0,255]замість цього.
Кевін Кройсейсен

@KevinCruijssen Насправді код для фільтрації недійсних символів не працював, оскільки я забув змінити змінну у внутрішньому циклі. Слід виправити зараз.
Ніл

2

Сітківка , 46 44 байти

^
.
^(\.(25[0-5]|(2[0-4]|1\d|[1-9])?\d)){4}$

Порт відповіді Java @ OlivierGrégoire , тому не забудьте підтримати його!
-2 байти завдяки @Neil .

Спробуйте в Інтернеті .

Пояснення:

^
.                           # Prepend a dot "." before the (implicit) input
^...$                       # Check if the entire string matches the following regex
                            # exactly, resulting in 1/0 as truthy/falsey:
 (                          #  Open a capture group
  \.                        #   A dot "."
    (25[0-5]                #   Followed by a number in the range [250,255]
    |(2[0-4]|         ) \d) #   or by a number in the range [200,249]
    |(      |1\d|     ) \d) #   or by a number in the range [100,199]
    |(          |[1-9]) \d) #   or by a number in the range [10,99]
    |(                )?\d) #   or by a number in the range [0,9]
 )                          #  Close capture group
  {4}                       #  This capture group should match 4 times after each other

Моя спроба (яку я не публікував, тому що питання було зупинено на той час) була однакової довжини, але не мала \dоптимізації групи, тому ви можете зберегти два байти, тому що вам не потрібна Mспецифікація на останній рядок
Ніл

Мені вдалося звести Retina до 42 байт, перенісши відповідь Perl 6, але ця відповідь також працює в 0.8.2, а мій порт не відповідає.
Ніл

2

Желе , 11 байт

⁹ḶṾ€ṗ4j€”.ċ

102564=4294967296 адрес, а потім підраховує кількість входів вхідних даних.

16256 ( ), оскільки метод настільки неефективний!

Як?

⁹ḶṾ€ṗ4j€”.ċ - Link: list of characters, S
⁹           - literal 256
 Ḷ          - lowered range = [0,1,2,...,254,255]
  Ṿ€        - unevaluate €ach = ['0','1',...,['2','5','4'],['2','5','5']]
    ṗ4      - 4th Cartesian power = ALL 256^4 lists of 4 of them
            -               (e.g.: ['0',['2','5','5'],'9',['1','0']])
        ”.  - literal '.' character
      j€    - join for €ach (e.g. ['0','.','2','5','5','.','9','.','1','0'] = "0.255.9.10")
          ċ - count occurrences of right (S) in left (that big list)

Чому версія з 65 536 IP-адресами займає 1,8 секунди? o_O
Денніс

2

Сітківка , 42 41 байт

~(K`

255*
["^(("|'|]")\.?\b){4}$"L$`
$.`

Спробуйте в Інтернеті! На основі попередньої версії відповіді Perl 6 @ nwellnhof, але 1 байт збережено, вкравши \.?\bтрюк з відповіді @ Deadcode. Пояснення:

K`

Очистіть робочу зону.

255*

Вставте 255 символів.

["^(("|'|]")\.?\b){4}$"L$`
$.`

Створіть діапазон 0..255, розділений |s, з префіксом ^((та суфіксом )\.?\b){4}$, будуючи таким чином регулярний вираз ^((0|1|...255)\.?\b){4}$.

~(

Оцініть це на оригінальному введенні.


1

Піп , 25 16 байт

a~=X,256RL4J"\."

Приймає IP-адресу кандидата як аргумент командного рядка. Спробуйте в Інтернеті! або Перевірте всі тестові випадки

Пояснення

Рішення Regex, по суті, порт рекурсивної відповіді Стакса .

                  a is 1st cmdline arg (implicit)
    ,256          Range(256), i.e. [0 1 2 ... 255]
   X              To regex: creates a regex that matches any item from that list
                  i.e. essentially `(0|1|2|...|255)`
        RL4       Create a list with 4 copies of that regex
           J"\."  Join on this string
 ~=               Regex full-match
a                 against the input

1

JavaScript, 89 байт

(_,r=`(${[...Array(256).keys()].join`|`})`)=>RegExp(`^${(r+'\\.').repeat(3)+r}$`).test(_)

Спробуйте в Інтернеті!

Створіть RegExpгрупи захоплення з індексів масиву, що має length 256для 0-255об'єднаного діапазону |та за ним слідує уникнутий .символ ( ^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$), повторний 3час закриття об'єднаним масивом з подальшим $узгодженням кінця рядка, повернення trueабо falseрезультату вводу, переданого до RegExp.prototype.test().

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.