Adresse IP ou non?

25

Votre outil d'analyse de réseau est particulièrement difficile à saisir et se bloque immédiatement si vous lui fournissez une adresse IPv4 qui contient des caractères incorrects ou n'est pas correctement formatée.

Une adresse IPv4 est une adresse numérique 32 bits écrite en quatre nombres séparés par des points. Chaque nombre peut être compris entre zéro et 255 .

Nous devons écrire un outil pour pré-valider l'entrée pour éviter ces plantages, et notre outil spécifique est difficile: un format valide ressemblera à l' a.b.c.dendroit où a, b, c et d:

  • Peut être un 0ou un nombre naturel sans zéros non significatifs .
  • Doit être compris entre 0 et 255 (inclus).
  • Devrait pas contenir des symboles spéciaux comme +, -, ,et d' autres.
  • Doit être décimal (base 10)

Entrée : une chaîne

Sortie : valeur Truthy ou Falsey (valeurs arbitraires également acceptées)

Cas de test :

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)

Il s'agit de , donc le moins d'octets gagnera!

Remarque pour les utilisateurs - si vous souhaitez ajouter d'autres cas de test, vous êtes les bienvenus (en suggérant une modification). Mais assurez-vous que les cas de test ne se répètent pas! Merci

rv7
la source
10
Proposer 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
Suggérez d'ajouter des cas de test "1.2.3.4.5" (pour exclure les adresses IP trop longues) et "999.0.0.0" (pour exclure les adresses IP trop grandes).
Triggernométrie
5
Peut-être un peu difficile, mais vous devriez probablement vous référer aux "adresses IPv4" plutôt qu'aux "adresses IP" - ou du moins, mentionner quelque part que vous voulez juste dire des adresses IPv4 - sinon 1234: 5678 :: 1 devrait être une adresse IP valide (alors que d'après la description, il est clair que ce n'est pas prévu :)
psmears
3
@Criggie La prémisse n'est pas de vérifier réellement toutes les vraies règles IP4 (comme celles que vous avez mentionnées), c'est de s'assurer que la chaîne d'entrée ne plante pas une autre application (probablement mal écrite) qui n'autorise l'entrée que sous une forme très spécifique . De plus, nous n'allons pas changer les règles d'un défi qui a déjà plus de 30 réponses.
BradC
2
@Criggie Il convient de noter que la RFC déclare que "les adresses ont une longueur fixe de quatre octets". Je pense que les cas marginaux auxquels vous faites référence sont plus spécialisés que ce défi.
Poke

Réponses:

26

Code machine X86_64: 18 16 octets

Edit: Cette réponse ne fonctionne pas tout à fait, car

  1. J'utilise inet_ptondes bibliothèques C standard, ce qui signifie que j'ai besoin de l'extern. Je n'ai cependant pas inclus l'extern dans mon nombre d'octets.
  2. J'ai utilisé la zone rouge en conséquence pour l'adresse réelle, mais j'ai appelé une fonction qui aurait également pu utiliser la zone rouge. Heureusement, cela ne fonctionne pas sur ma machine, mais une compilation de bibliothèque standard étrange pourrait l'utiliser, ce qui pourrait entraîner un comportement indéfini.

Et oui, le tout se fait à peu près par une fonction déjà écrite

Quoi qu'il en soit, c'est ce que j'ai obtenu: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Assemblée:

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

Explication:

Jetez un oeil à inet_pton(3). Il prend une adresse IP de chaîne et la place dans un tampon que vous pouvez utiliser avec struct sockaddr. Il prend 3 arguments: la famille d'adresses ( AF_INET(ipv4), 2 ou AF_INET6(ipv6), 10), la chaîne de l'adresse ip et un pointeur vers la sortie. Il renvoie 1 en cas de succès, 0 pour une adresse non valide ou -1 pour lorsque la famille d'adresses n'est ni l'un AF_INETni l'autre AF_INET6(ce qui ne se produira jamais car je lui passe une constante).

Je déplace donc simplement la chaîne vers le registre pour le deuxième argument, je mets le premier registre à 2 et je mets le troisième registre dans la zone rouge (128 octets en dessous du pointeur de pile) car je me fiche du résultat. Ensuite , je peux tout simplement jmppour inet_ptonet laisser que le retour directement à l'appelant!

J'ai fait tourner ce programme de test rapide pour tester vos cas:

#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;
}

Assemblez avec nasm -felf64 assembly.asm, compilez avec gcc -no-pie test.c assembly.o, et vous obtiendrez:

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

Je pourrais rendre cela beaucoup plus petit si l'appelant devait passer AF_INETou AF_INET6à la fonction

user233009
la source
4
J'adore que tu aies fait ça en asm. Et le fait que vous l'ayez expliqué à ceux qui pourraient ne pas le comprendre (ainsi que le code de test) est encore mieux. Ce qui ne veut pas dire que j'aurais pu le faire en toute simplicité; beaucoup trop d'années se sont écoulées, mais je me souviens suffisamment pour voir exactement ce que dit votre explication (et donc votre processus). Bon travail.
Pryftan
4
e9 00 00 00 00est un jmp near $+5, pas un jmp inet_pton. Si vous fournissez un opcode, vous devez inclure la inet_ptonpartie incluse , ne pas laisser de blanc
l4m2
1
15 octets-TIO 32bit x86
Logern
3
vous devez inclure l'extern dans le titre de la réponse, car le programme l'exige et il n'est pas disponible sur toutes les plateformes.
qwr
1
le "mov rdi, 2" peut être "push 2 / pop rdi" pour -2 octets. Notez également que le démontage est incorrect ou que le code est incorrect. C'est soit "mov edi" (pas rdi) soit il manque un préfixe.
peter ferrie
13

Java (JDK) , 63 octets

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

Essayez-le en ligne!

Crédits

  • -1 octet grâce à Kevin Cruijssen
  • l4m2 pour montrer le cas précédemment défaillant .1.1.1.1.
Olivier Grégoire
la source
Vous avez oublié de supprimer le point-virgule arrière. ;) Et je peux vérifier que cela fonctionne pour tous les cas de test, y compris ceux dans les commentaires. Va voir si je vois des choses au golf.
Kevin Cruijssen du
3
Échec.1.2.3.4
l4m2
Est-il autorisé à utiliser booléen lorsque explicitement besoin de 0/1?
l4m2
1
@ l4m2 La question d'origine avait Valid / Invalid. Je suppose donc que toute valeur truey / falsey est acceptable ici.
Kevin Cruijssen du
Output: 0 or 1et Java n'a pas d'auto bool-> int
l4m2
12

JavaScript (Node.js) , 43 octets

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

Essayez-le en ligne!

JavaScript (Node.js) , 46 octets

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

Essayez-le en ligne!

utilisé la partie d'Arnauld

JavaScript (Node.js) , 54 53 51 octets

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

Essayez-le en ligne!

-2B pour 0+t<256, -1B de Patrick Stephansen, + 1B pour éviter l'entrée1.1.1.1e-80

Solution RegExp 58 54 octets

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

Merci Deadcode pour 3 octets

l4m2
la source
J'ai ajouté quelques cas de test!
rv7
Cela donne la vérité pour 0.0.0.0. Tout le reste semble bien fonctionner.
Kevin Cruijssen
1
@KevinCruijssen 0.0.0.0est ici vrai. Pourquoi l'injection SQL est là?
l4m2
Ah, attendez, j'ai mal interprété la phrase dans la description du défi. 0.0.0.0est en effet véridique. Cela répondra aussi à ma réponse .. (Et que voulez-vous dire par injection SQL?: S Le lien est vers TIO avec TOUS les cas de test.)
Kevin Cruijssen
1
@ l4m2 Je l'ai ajouté car nous avons besoin de quelques tests qui ne ressemblent même pas à une adresse IP.
tsh
11

PHP , 39 36 octets

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

Essayez-le en ligne!

275 ressemble à la constante FILTER_VALIDATE_IP

5 ** 9 est utilisé à la place de la constante FILTER_FLAG_IPV4. C'est suffisant, car 5**9 & FILTER_FLAG_IPV4c'est vrai, c'est exactement ce que fait PHP en arrière-plan, comme l'a souligné Benoit Esnard.

Ici, filter_varrenvoie le premier argument, s'il s'agit d'une adresse IPv4 valide, ou faux s'il ne l'est pas. Avec +!!, nous produisons la sortie requise par le défi.

oktupol
la source
3
Utiliser 5**9au lieu d' 1048576enregistrer 3 octets ici: PHP utilise &pour tester les drapeaux IPv4 / IPv6 , donc tout nombre compris entre 1048576 et 2097151 est valide.
Benoit Esnard
Par la présente, je dévalise votre réponse pour être (essentiellement) ma réponse: codegolf.stackexchange.com/a/174470/14732 qui a été écrit le 2018-10-22 09: 17: 34UTC tandis que la vôtre a été écrite le 2018-10-22 09: 21: 55UTC. Même si je reviens à l'optimisation à 1 octet donnée par @BenoitEsnard, ma réponse est exactement la même que la vôtre en termes de fonctionnalité.
Ismael Miguel
2
Je dois m'excuser, je n'ai pas vu votre réponse, bien qu'au moment où je l'ai composée, il n'y avait pas de soumission en PHP sur cette question (comme vous l'avez dit, le décalage horaire est inférieur à cinq minutes).
oktupol
Je sais et je le comprends. Je viens juste de remarquer le vôtre. Je peux faire reculer le mien, et vous gardez l'optimisation. Mais je ne sais pas si cela rend la réponse suffisamment différente les unes des autres.
Ismael Miguel
17
@IsmaelMiguel Je ne voterais pas pour quelqu'un si c'est plausible que la vôtre n'était pas là quand ils ont commencé. Avec une différence de 5 minutes, non seulement c'est plausible, c'est presque certainement le cas, ce qui est évident même sans que l'auteur ne le dise lui-même.
Duncan X Simpson
11

PHP, 36 octets

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

ip2longest une fonction intégrée bien connue .

rexkogitans
la source
3
29 octets
nwellnhof
Cela semble utiliser des fonctionnalités non documentées présentes dans les versions plus récentes (je suppose que cela vient de PHP7 +). Gardez à l'esprit que, pour PHP 4 et 5, cela accepte les adresses IP incomplètes.
Ismael Miguel
27 octets
Mark
1
Cela donnera du succès si vous l'introduisez dans un entier, tel que 1, 2, etc. Ne pensez pas que cela devrait. Et aussi si vous l'introduisez quelque chose comme 100.100.100
nl-x
10

Perl 6 , 22 21 20 octets

-1 octet grâce à Phil H.

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

Essayez-le en ligne!

Explication

{                  }  # 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
nwellnhof
la source
3
Mec, je dois passer plus de temps à comprendre les expressions rationnelles de Perl 6. Je n'avais pas non plus le %modificateur existait. Je me demande s'il essaie de vérifier toutes les 256**4possibilités?
Jo King
1
Au lieu de <{^256}>vous, vous pouvez simplement convertir la plage en un tableau @(^256)pour -1 caractère TIO . En changeant le bloc de code en un tableau, cela devient également beaucoup plus rapide (0,4 s au lieu de> 30).
Phil H
@PhilH Cool, merci. J'ai essayé $(^256)mais maintenant je comprends pourquoi cela n'a pas fonctionné.
nwellnhof
9

05AB1E , 26 24 23 22 23 octets

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

-1 octet grâce à @Emigna .
+1 octet pour le cas de test de correction de bogue 1.1.1.1E1renvoyant incorrectement un résultat véridique.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

'.¡              '# 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)
Kevin Cruijssen
la source
1
Vous devriez pouvoir utiliser à la Āplace de<d
Emigna
@MagicOctopusUrn Je crains qu'il échoue pour 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255et 0.00.10.255. (PS: j'ai corrigé le 1.1.1.1E1þ
problème
Assez juste, j'ai pensé que j'avais raté quelque chose.
Urne de poulpe magique
@MagicOctopusUrn Le problème principal est que 05AB1E voit des nombres avec des 0 en tête égaux à ceux sans, même sous forme de chaîne. Quelle est la raison pour laquelle j'utiliser le DïþJsJQchèque où ïjeter aux int pour enlever grands 0s, et þque les feuilles chiffres des choses comme la suppression E, -etc. :) Le est pour le cas de test 0.00.10.255, puisque 00010255et 0010255serait égale.
Kevin Cruijssen
Oui, je suis passé par le même non-sens, l'inversion de tous les chiffres a plutôt bien fonctionné, sauf dans ces cas. Intéressant lorsque les fonctionnalités bénéfiques pour certains problèmes deviennent presque des bogues pour d'autres.
Magic Octopus Urn
6

PowerShell, 59 51 49 octets

-8 octets, merci @AdmBorkBork

-2 octets, trueou falseautorisé par l'auteur

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

Script de test:

$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"
}

Sortie:

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

Explication:

Le script essaie d'analyser une chaîne d'arguments pour construire un objet .NET, IPAddress .

  • retourner $truesi objectcréé et l'argument chaîne est égal à une représentation sous forme de chaîne de object(adresse normalisée par object.toString())
  • retourner $falseautrement

PowerShell, 59 56 54 octets, 'n'utilisez pas d'alternative .NET lib'

-3 octets, trueou falseautorisé par l'auteur

-2 octets, merci à @ Deadcode pour la regexp cool.

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

Essayez-le en ligne!

Merci @ Olivier Grégoire pour l'expression régulière originale.

mazzy
la source
1
Vous ne devriez pas avoir besoin d'appeler |% t*gcar PowerShell convertira automatiquement le côté droit de -eqsous forme de chaîne, car le côté gauche est une chaîne. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork
Vous pouvez graver 2 octets de la version "n'utilisez pas de lib .NET" en utilisant mon expression régulière (adaptée à l'astuce d'insertion d'une période, qui bien sûr ne peut pas être dans ma version car c'est une expression régulière pure): tio.run/…
Deadcode
5

C (gcc) / POSIX, 26 octets

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

Essayez-le en ligne!

Fonctionne comme du code 64 bits sur TIO mais nécessite probablement cela sizeof(int) == sizeof(char*)sur d'autres plateformes.

nwellnhof
la source
@TobySpeight Oui, si vous êtes sur x86, vous devriez probablement essayer en mode 32 bits ( -m32).
nwellnhof
Je l'ai fait fonctionner, en passant scomme char*(pas d'accès à un système ILP32 ici), et oui, je me mélangeais avec inet_aton().
Toby Speight
5

PHP 7+, 37 35 32 octets

Cela utilise la fonction intégrée filter_var, pour valider qu'il s'agit d'une adresse IPv4 .

Pour que cela fonctionne, vous devez passer la clé isur une demande GET.

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

Ne produira rien (pour un falsyrésultat) ou l'IP (pour un truthyrésultat), selon le résultat.

Vous pouvez essayer ceci sur: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Cela utilise directement les valeurs suivantes:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (qui a le bit requis comme "1", pour 1048576)

Merci à Benoit Esnard pour cette astuce qui m'a fait économiser 1 octet!

Merci à Titus de m'avoir rappelé les changements apportés au défi.


J'ai cherché à utiliser la fonction ip2long, mais elle fonctionne avec des adresses IP non complètes.

Les adresses IPv4 non complètes sont considérées comme non valides dans ce défi.

S'ils étaient autorisés, ce serait le code final (uniquement pour PHP 5.2.10):

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

Actuellement, il n'est pas explicite dans la documentation que cela cessera de fonctionner (en cas de passage d'une adresse IP incomplète) avec les versions PHP plus récentes.

Après les tests, a confirmé que c'était le cas.

Merci à nwellnhof pour le conseil!

Ismael Miguel
la source
Utiliser 5**9au lieu d' 1<<20enregistrer un octet ici: PHP utilise &pour tester les drapeaux IPv4 / IPv6 , donc tout nombre compris entre 1048576 et 2097151 est valide.
Benoit Esnard
Dans les versions PHP plus récentes, ip2longn'autorise pas les adresses incomplètes.
nwellnhof
@BenoitEsnard Merci! Je l'ai ajouté à la réponse
Ismael Miguel
@nwellnhof Après les tests, je confirme que c'est le cas. Cependant, je ne pense pas que ce soit une bonne idée de l'utiliser, car il n'est pas explicitement documenté.
Ismael Miguel
+!!n'est pas requis; le PO accepte désormais des valeurs de vérité arbitraires.
Titus
5

Python 3: 81 78 70 69 66 octets

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

Parcourez toutes les adresses IPv4 possibles, obtenez la représentation sous forme de chaîne et comparez-la à l'entrée. Ça prend du temps à courir.

EDIT: Suppression de 3 octets en passant du programme complet à la fonction anonyme.

EDIT2: Suppression de 8 octets avec l'aide de xnor

EDIT3: Suppression de 1 octet en utilisant une carte décompressée au lieu de la compréhension de la liste

EDIT4: Suppression de 3 octets en utilisant la compréhension de liste au lieu du ipaddressmodule

mypetlion
la source
2
Je pense que votre fonction anonyme peut l'être [str(ip_address(x))for x in range(256**4)].count. , Aussi 256**4peut être 16**8.
2018
5

C # (Visual C # Interactive Compiler) , 84 79 65 octets

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

Essayez-le en ligne!

-5 et -14 octets enregistrés grâce à @dana!

# C # (Visual C # Interactive Compiler) , 61 octets

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

Essayez-le en ligne!

Ceci est un travail en cours de réalisation. Le code utilise System.Net(+17 octets si vous le comptez). si vous vous demandez pourquoi je compte et analyse:

La limitation avec la méthode IPAddress.TryParse est qu'elle vérifie si une chaîne peut être convertie en adresse IP, donc si elle est fournie avec une valeur de chaîne comme "5", elle la considère comme "0.0.0.5".

la source

Comme l'a dit @milk en commentaire, il échouera en effet sur les zéros non significatifs. Ainsi, le 61 octets ne fonctionne pas.

aloisdg dit Réintégrer Monica
la source
1
@dana great. Bien fait! Quatre de plus et il battra les solutions de 61 octets!
aloisdg dit Réintégrer Monica le
4

Python 2 , 85 82 81 octets

-1 octet grâce à Kevin Cruijssen

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

Essayez-le en ligne!

La réponse à 113 octets est supprimée car elle échoue pour1.1.1.1e-80

Possum mort
la source
1
Vous pouvez jouer print 1*rau golf print~~r. +1 cependant, car il semble fonctionner pour tous les cas de test possibles suggérés jusqu'à présent . PS: Votre réponse de 113 octets échoue 1.1.1.1e-80.
Kevin Cruijssen
@KevinCruijssen Merci! Je n'ai pas pensé à une telle notation des nombres
Dead Possum
N'est-ce pas ipaddressun module Python 3?
Farhan.K
@ Farhan.K Dunno, mais cela fonctionne dans TIO
Dead Possum
4

Japt, 17 15 octets

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

Essayez-le ou exécutez tous les cas de test ou vérifiez des cas de test supplémentaires à partir des commentaires de défi


Explication

Nous divisons en un tableau activé ., vérifions que la longueur de ce tableau est égale à 4ET que la longueur lorsque tous les éléments de la plage en ["0","255"]sont supprimés est 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
Hirsute
la source
Bonne réponse. Également vérifié pour tous les cas de test suggérés jusqu'à présent . Curieux de voir cette explication.
Kevin Cruijssen
2
@KevinCruijssen, explication ajoutée. Merci pour ces cas de test supplémentaires.
Shaggy
3

Mathematica, 39 31 octets

Version originale:

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

Version modifiée (merci à Misha Lavrov)

 AtomQ@*Interpreter["IPAddress"]

qui retourne Truesi l'entrée est une adresse IP valide ( essayez-la ).

Au cas où vous insisteriez pour obtenir 1 et à la 0place, 7 octets supplémentaires seraient nécessaires:

Boole/@AtomQ@*Interpreter["IPAddress"]
polfosol ఠ_ఠ
la source
Étant donné que Interpreter["IPAddress"]renvoie une chaîne pour une entrée valide et un objet d'échec compliqué pour une entrée non valide, nous pouvons tester les entrées valides avec AtomQ[Interpreter["IPAddress"][#]]&, qui peuvent être encore raccourcies à la composition de la fonction AtomQ@*Interpreter["IPAddress"]. Essayez-le en ligne!
Misha Lavrov
Échoue sur une adresse IPv6 comme 2001:0db8:85a3:0000:0000:8a2e:0370:7334.
lirtosiast
3

JavaScript (ES6), 49 octets

Renvoie une valeur booléenne.

s=>[0,1,2,3].map(i=>s.split`.`[i]&255).join`.`==s

Essayez-le en ligne!

Arnauld
la source
3

Python 2, 93 89 67 53 octets

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

Essayez-le en ligne!

Merci à Dennis d'avoir rasé encore 14 octets sur les comparaisons internes et le code de sortie.

Un merci spécial à Jonathan Allan pour le rasage de 22 octets et un correctif logique! Pesky essayer / sauf Begone!

Prendre des chaînes correctement formatées au lieu d'octets bruts rase 4 octets, merci Jo King.

TemporalWolf
la source
Votre chèque peut être joué au golf i==`int(i)&255` . En outre, vous pouvez forcer une erreur avec [...]!=[1]*4>_, car vous utilisez quand même des codes de sortie. Essayez-le en ligne!
Dennis
@Dennis Je ne comprends pas ce qui >_fait. Le bit à bit et est assez ingénieux cependant ... Je n'ai pas réussi à les combiner moi-même.
TemporalWolf
2
Si !=renvoie False, Python court-circuite et rien ne se passe; l'interprète sort normalement. S'il renvoie True, >_déclenche une erreur NameError, car la variable _n'est pas définie.
Dennis
Les chiffres que j'enchaîne les comparaisons dans ma réponse et ensuite manquer le résultat évident dans votre commentaire. Merci pour l'explication.
TemporalWolf
3

sfk , 176 octets

* était à l'origine Bash + SFK mais TIO a depuis ajouté un wrapper SFK approprié

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

Essayez-le en ligne!

Οurous
la source
Est-ce que la première vérification de l'impression d'erreur serait nc [addr] 1 -w1raccourcie?
@Rogem ncaccepte les zéros de tête ainsi que les adresses IPv6, donc je devrais encore les gérer - et cela est plus destiné à une sfkréponse qu'à une réponse shell de toute façon.
2018
3

Python3 Bash * 60

* Aussi d'autres coquilles. Toute personne pour laquelle le test de vérité / fausse passe sur un code de sortie de programme

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

Explication

Le problème avec une solution Python pure est qu'un crash de programme est considéré comme indéterminé. Nous pourrions utiliser un "lot" de code pour convertir une exception en une valeur vraie / fasly appropriée. Cependant, à un moment donné, l'interpréteur Python gère cette exception non interceptée et retourne un code de sortie non nul. Pour le faible coût de changement de langue vers votre shell Unix préféré, nous pouvons enregistrer un peu de code!

Bien sûr, cela est vulnérable aux attaques par injection ... Des entrées telles que 1.1.1.1'); print('Doing Something Evilsont une menace non atténuée!

Sompom
la source
( Explication c'est (pas Explication ).)
Peter Mortensen
@PeterMortensen Yikes. It was even underlined in red. My browser tried to save me, but I wouldn't listen. Thanks for catching that!
Sompom
Les programmes complets sont autorisés à sortir via des codes de sortie, donc cela pourrait être de 43 octets .
ბიმო
@BMO Intéressant. Merci d'avoir fait remarquer cela! Je pense que la définition du problème est passée de "Truthy / Falsy" à également autoriser une sortie arbitraire depuis que j'ai posté cela, mais je n'aurais tout simplement pas remarqué auparavant :)
Sompom
3

ECMAScript regex pur, 41 octets

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

Essayez-le en ligne!
Essayez-le sur regex101

Je pense que la logique de ce regex parle d'elle-même, donc je vais simplement faire une jolie impression mais pas le commenter:

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

Cela peut être utilisé pour raser 2 octets des autres réponses suivantes:

Here is an alternative version that allows leading zeros, but does so consistently (octets may be represented by a maximum of 3 decimal digits):

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

Or allow any number of leading zeros:

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

Deadcode
la source
1
\b and \B... it's smart!
mazzy
1
@mazzy Yes, those two really come in handy! I could've used (?!0\d) instead, but I like \B better!
Deadcode
The powershell answer doesn't get shorter with your regexp. I'm sorry. Quotes are needed to convert an array to a string. Try it online!
mazzy
1
The \.?\b saved me a byte on my answer too, thanks!
Neil
1
Saved 3 bytes thx
l4m2
2

Red, 106 bytes

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]

Try it online!

Returnd true or false

Explanation:

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
]
Galen Ivanov
la source
2

Stax, 14 bytes

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

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

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?

Run this one

recursive
la source
Surprised to know that you made the language Stax! it is working well.
rv7
Thanks! The space of golfing languages is surprisingly crowded, and I'm not sure if stax can justify its own existence on its merits, but my main goal was just to see if I could do it and maybe learn something. It ended up being more fun than expected.
recursive
2

Python 3, 109 93 bytes

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

Explanation

Each octet can be 0 - 255 :

  • starts with 25 and having 0-5 as last digit
  • start with 2, has 0-4 as second digit and any digit at the end
  • starts with 1, and 00 - 99 as rest digits
  • has only 2 digits - 1-9 being the first one and any digit thereafter
  • or just a single digit

An octet can end with a (.) or just end, with the condition that it cannot do both , the negative lookahead (?!$) takes care of this case

Thanks @Zachary for making me realize I can discard spaces (since it is code golf)
Thanks @DLosc for the improvements and making me realize my mistake, its been corrected now.

alpheus
la source
2
Some explanation for this might help.
Nissa
x: re.match=>x:re.match; , x => ,x, and ) is => )is should save 3 bytes. Also, in the regex, you can use \d for each occurrence of [0-9], and [1]=>1. This seems like a great first post, though!
Zacharý
[1-9][0-9]|[0-9] can become [1-9]\d|\d (per Zacharý's advice), which can become [1-9]?\d. Also, instead of testing re.match(...)is not None, you can do bool(re.match(...)) since match objects are truthy and None is falsey. :)
DLosc
Hmm. Actually, this fails on the test case 1.2.3.4.5 (and also 1.2.3.4., which isn't in the official list of test cases), because it can match a period instead of end-of-string after the fourth number.
DLosc
2

Bash, 30 bytes

ipcalc -c `cat`;echo $(($?^1))

Try it online!

Logern
la source
The echo $(($?)) part is not needed since programs are allowed to output their result via exit code.
ბიმო
2

Charcoal, 45 21 bytes

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

Try it online! Link is to verbose version of code. Edit: Saved 24 bytes by porting @Shaggy's Japt answer. Explanation:

    θ                   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
Neil
la source
Fails for test cases with negative integers like 123.-50.0.12 or 1.1.1.-80. Everything else seems to work fine. So the <256 check should be in [0,255] instead.
Kevin Cruijssen
@KevinCruijssen Actually the code to filter out invalid characters wasn't working because I forgot to change the variable in the inner loop. Should be fixed now.
Neil
2

Retina, 46 44 bytes

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

Port of @OlivierGrégoire's Java answer, so make sure to upvote him!
-2 bytes thanks to @Neil.

Try it online.

Explanation:

^
.                           # 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
Kevin Cruijssen
la source
My attempt (which I didn't post because the question got put on hold at the time) was the same length, but didn't have the \d group optimisation, so you can save two bytes because you don't need the M specification on the last line.
Neil
I managed to get Retina down to 42 bytes by porting the Perl 6 answer but this answer also works in 0.8.2 which my port doesn't.
Neil
2

Jelly, 11 bytes

⁹ḶṾ€ṗ4j€”.ċ

A monadic link accepting a list of characters which yields 1 if it's a valid address and 0 otherwise. Builds a list of all 2564=4294967296 addresses and then counts the number of occurrences of the input therein.

Here's similar @ Try it online! that uses 16 () rather than 256 (), since the method is so inefficient!

How?

⁹ḶṾ€ṗ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)
Jonathan Allan
la source
Why does the version with 65,536 IPs take 1.8 seconds? o_O
Dennis
2

Retina, 42 41 bytes

~(K`

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

Try it online! Based on a previous version of @nwellnhof's Perl 6 answer, but 1 byte saved by stealing the \.?\b trick from @Deadcode's answer. Explanation:

K`

Clear the work area.

255*

Insert 255 characters.

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

Generate the range 0..255 separated with |s, prefixed with ^((, and suffixed with )\.?\b){4}$, thus building the regular expression ^((0|1|...255)\.?\b){4}$.

~(

Evaluate that on the original input.

Neil
la source
1

Pip, 25 16 bytes

a~=X,256RL4J"\."

Takes the candidate IP address as a command-line argument. Try it online! or Verify all test cases

Explanation

Regex solution, essentially a port of recursive's Stax answer.

                  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
DLosc
la source
1

JavaScript, 89 bytes

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

Try it online!

Create RegExp capture groups from indexes of an array having length 256 for range 0-255 joined with | and followed by escaped . character (^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$) repeated 3 times closing with joined array followed by $ to match end of string, return true or false result of input passed to RegExp.prototype.test().

guest271314
la source