Défi
Étant donné un IPv4 address
en notation quadrillée et un IPv4 subnet
en notation CIDR , déterminez si le address
est dans le subnet
. Sortez une valeur distincte et cohérente si elle est dans le subnet
, et une valeur distincte distincte et cohérente si elle n'est pas dans le subnet
. Les valeurs de sortie ne doivent pas nécessairement être véridiques / falsey dans votre langue.
Brève introduction à la notation du sous-réseau CIDR
Les adresses réseau IPv4 ont une longueur de 32 bits, divisées en quatre groupes de 8 bits pour faciliter la lecture. La notation de sous-réseau CIDR est un masque du nombre spécifié de bits, commençant à l'extrême gauche. Par exemple, pour un /24
sous - réseau, cela signifie que les 8 bits les plus à droite de l'adresse sont disponibles dans ce sous-réseau. Ainsi, deux adresses qui sont séparées par au plus 255
et qui ont le même masque de sous-réseau se trouvent dans le même sous-réseau. Notez que les CIDR valides ont tous les bits d'hôte (le côté droit) non définis (zéros).
xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^--- subnet mask ---^ ^-hosts-^
Pour un autre exemple, un /32
sous - réseau spécifie que tous les bits sont le masque de sous-réseau, ce qui signifie essentiellement qu'un seul hôte est autorisé par /32
.
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^--- subnet mask ---^
Exemples:
Utiliser True
pour "dans le sous-réseau" et False
pour "pas dans le sous-réseau" en sortie:
127.0.0.1
127.0.0.0/24
True
127.0.0.55
127.0.0.0/23
True
127.0.1.55
127.0.0.0/23
True
10.4.1.33
10.4.0.0/16
True
255.255.255.255
0.0.0.0/0
True
127.1.2.3
127.0.0.0/24
False
127.1.2.3
127.1.2.1/32
False
10.10.83.255
10.10.84.0/22
False
Règles et clarifications
- Étant donné que l'analyse des entrées n'est pas le point intéressant de ce défi, vous êtes assuré d'obtenir des adresses IPv4 et des masques de sous-réseau valides.
- L'entrée et la sortie peuvent être fournies par n'importe quelle méthode pratique .
- Vous pouvez imprimer le résultat dans STDOUT ou le renvoyer en tant que résultat de fonction. Veuillez indiquer dans votre soumission les valeurs que la sortie peut prendre.
- Un programme complet ou une fonction sont acceptables.
- Les failles standard sont interdites.
- Il s'agit de code-golf, donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
la source
10.0.0.1/10.0.0.0”/16
?1.255.1.1/8
est une expression CIDR valide , représentant l'hôte1.255.1.1
au sein du réseau1.0.0.0
avec un masque de sous-réseau de255.0.0.0
. Cependant, le défi demande le numéro de réseau et le sous-réseau spécifiquement en notation CIDR, qui1.255.1.1/8
n'est pas une combinaison de numéro de réseau et de sous-réseau valide.Réponses:
Python 3 (62 octets)
Très simple:
la source
ip_adress
objet et unip_network
objet constituentany convenient method
, laissant peut-être gagner Python, à moins qu'un langage de golf basé sur python n'ait ces types?(host^net)>>(32-mask)
n'est que de 10 octets. Mais c'est à mi-chemin entre les tâches n'impliquant pas de listes de listes ou mappant une fonction sur une liste, car de nombreuses opérations scalaires peuvent être effectuées avec une instruction de 2 ou 3 octets, et des boucles peuvent être construites autour de choses en quelques octets.C # (Visual C # Compiler) , 250 + 31 = 281 octets
Bytecount comprend
using System;using System.Linq;
Essayez-le en ligne!
J'ai écrit cela dans JS dès que le défi a été publié, mais Arnauld m'a battu au poing avec une bien meilleure réponse, donc ici c'est en C # à la place.
Certainement beaucoup de place pour le golf.
Explication:
La fonction se compose d'une sous-fonction appelée
h
:Cette sous-fonction divise l'adresse IP
.
, convertit chaque nombre en une chaîne binaire, remplit chaque chaîne de gauche avec0
une longueur de 8 bits, puis concatène les chaînes en une chaîne binaire de 32 bits.Cela se fait immédiatement sur place avec
a=h(a);
l'adresse IP donnée.Nous avons ensuite divisé le masque de sous-réseau en une adresse IP et un numéro de masque avec
c=b.Split('/');
Le composant d'adresse IP est également transmis via notre sous-fonction:
b=h(c[0]);
et le numéro de masque est analysé en un entier:var d=int.Parse(c[1]);
Enfin, nous prenons les premiers
d
bits des deux chaînes binaires (oùd
est le numéro de masque) et les comparons:return a.Substring(0,d)==b.Substring(0,d);
la source
rPad
est une chaîne intégrée. lien pastebin vers le lien TIO qui est trop long seulShell Linux POSIX (avec net-tools / iputils) (34 octets sans terminaison, 47 octets avec terminaison)
Qu'est-ce qui convient le mieux pour analyser les masques et les adresses réseau que les utilitaires réseau eux-mêmes? :)
Attention: le script peut potentiellement endommager votre connectivité Internet, veuillez l'exécuter avec précaution.
Entrée: le script prend l'adresse IP testée comme premier argument et le sous-réseau testé. comme deuxième argument.
Sortie: le script renvoie une valeur véridique (0) si le premier argument du script appartient au sous-réseau indiqué dans le deuxième argument. Sinon, il ne se terminera jamais.
Hypothèses: le script doit être exécuté en tant qu'utilisateur root, dans un environnement propre ( c'est-à - dire qu'aucune autre route blackhole n'a été définie par l'administrateur, et si une instance précédente du script a été exécutée, la route blackhole qu'il a créée a été supprimée ). Le script suppose également une "connexion Internet fonctionnelle" ( c'est -à- dire qu'une route par défaut valide est présente).
Explication:
Nous créons une route de trou noir vers le sous-réseau spécifié. Nous testons ensuite la connectivité à l'adresse IP fournie en utilisant ping . Si l'adresse n'appartient pas au sous-réseau (et puisque nous supposons une connexion Internet correctement définie), ping essaiera d'envoyer des paquets à cette adresse. Notez que la réponse de cette adresse n'a pas d'importance, car ping continuera d'essayer indéfiniment. Inversement, si l'adresse appartient au sous-réseau, le ping échouera avec ENETUNREACH et renverra 2, et puisque nous avons annulé la commande, le script réussira.
Exemple
Vérifier si 5.5.5.5 appartient à 8.8.8.0/24
(Nettoyer avec
sudo ip route del 8.8.8.0/24
après avoir exécuté la commande).Testez si 5.5.5.5 appartient à 5.5.5.0/24:
(Nettoyer avec
sudo ip route del 5.5.5.0/24
après avoir exécuté la commande).Testez si 8.8.8.8 appartient à 5.5.5.0/24:
(Nettoyer avec
sudo ip route del 5.5.5.0/24
après avoir exécuté la commande).Version 47 octets si nous interdisons les scripts sans terminaison
Selon le commentaire de @ Grimy, voici la version qui se termine toujours, et retourne 0 (véridique) si l'adresse est dans le sous-réseau, et 1 (faux) sinon. Nous faisons terminer ping avec l'
-c1
indicateur qui limite le nombre de paquets envoyés à 1. Si l'adresse a répondu, ping renverra 0, et sinon, ping renverra 1. Seulement si l'adresse appartient au sous-réseau blackholed, ping renverra 2, qui est donc ce contre quoi nous testons dans la dernière commande.la source
ping
je mourrais de SIGPIPE s'il fonctionnait avec stdout + stderr canalisé dans un autre programme, et que le lecteur fermait le tuyau. Et c'est le cas d'utilisation le plus probable, car le statut de sortie peut être réussi dans tous les cas (si nous avons ajouté une-c1
option de ping pour définir le nombre.) Mais bien sûr, la lecture de sa sortie avecvar=$(/a.sh)
échouerait; vous auriez besoin d'un lecteur qui s'est arrêté après avoir décidé, plutôt que de lire la sortie entière et de la regarder.ping
se terminera en moins d'une seconde, par exemple, en cas d'adresse noire). J'ai ajouté une version de terminaison pour 13 octets supplémentaires! :)JavaScript (ES6), 82 octets
Prend l'entrée comme
(address)(subnet)
. Renvoie une valeur booléenne.Essayez-le en ligne!
la source
PHP ,
1019288 octets-13 octets de @gwaugh
Essayez-le en ligne!
la source
function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
strtok()
. Le vôtre est 4 octets plus court que ma réponse très similaire ci-dessous. Accessoires!PowerPC / PPC64 C,
116114 octets(Testé sur x86_64 Ubuntu 18.04 à l'aide de powerpc64-linux-gnu-gcc -static et qemu-user.)
Le programme prend les deux lignes sur l'entrée standard et comme code de sortie, il renvoie 1 si l'adresse correspond et 0 si ce n'est pas le cas. (Cela dépend donc de la spécification ne nécessitant pas de valeur véridique pour une correspondance et une valeur de falsey pour une non-correspondance.) Notez que si vous exécutez de manière interactive, vous devrez signaler EOF (
^D
) trois fois après avoir entré la deuxième ligne.Cela repose sur PowerPC étant big-endian, et également sur cette plate-forme renvoyant 0 pour décaler à droite une valeur non signée de 32 bits par 32. Il lit les octets en valeurs non signées un par un, avec la longueur du masque de réseau dans un autre octet ; puis il prend le xor des deux adresses 32 bits non signées et décale les bits non pertinents. Enfin, il s'applique
!
pour satisfaire à l'exigence de ne renvoyer que deux valeurs distinctes.Remarque: Il peut être possible de raser deux octets en remplaçant
u+3
parp
et en exigeant une compilation avec-O0
. C'est vivre plus dangereusement que je ne le pense, cependant.Merci à Peter Cordes pour l'inspiration de cette solution.
Plus portable C,
186171167 octetsIci, je vais conserver une version plus portable qui fonctionne sur 167 octets.
Ce programme prend les deux lignes sur l'entrée standard et renvoie le code de sortie 1 si l'adresse est dans le sous-réseau et 0 si ce n'est pas le cas. (Cela dépend donc de la spécification ne nécessitant pas une valeur véridique pour les correspondances et une valeur de falsey pour les non-correspondances.)
Une ventilation de l'expression principale:
a^e
,b^f
,c^g
,d^h
Calcule le OU exclusif de l'adresse et le masque octet par octet.(((a^e)<<8|b^f)<<8|c^g)<<8|d^h
puis les combine en une seule valeur 32 bits non signée par une méthode de type Horner....>>32-n
décale ensuite les bits de la différence xor qui ne sont pas pertinents pour le masque de sous-réseau (en gardant à l'esprit que la-
priorité en C est plus élevée que<<
)~0U<<32
cela donnera un comportement indéfini en supposantunsigned
32 bits (ce qu'il est sur pratiquement toutes les plates-formes actuelles). D'un autre côté, si n = 0, alors n'importe quelle adresse correspondra, doncn&&...
donnera le résultat correct (en profitant du comportement de court-circuitage de&&
).!
sortie 0 ou 1.-15 octets en raison des commentaires de plafondcat et AdmBorkBork
-4 octets en raison du commentaire de Peter Cordes
la source
unsigned
. par exemple avecchar*p=&a
thenp++,p++,p++,...
oup--,...
as scanf args. La chaîne de format devrait"%hhu.%hhu..."
cependant être , c'est donc un compromis important entre cette taille supplémentaire et la déclaration de moins de vars et la possibilité de le faire(a^b)>>(32-count)
Stax , 22 octets
Exécuter et déboguer
Il prend les paramètres d'entrée séparés par des espaces sur l'entrée standard.
Déballé, non golfé et commenté, il ressemble à ceci.
Exécutez celui-ci
la source
Fonction de code machine x86-64,
5348 octetsjournal des modifications:
jz
sur le décalage au lieu d'utiliser un décalage 64 bits pour gérer le>>(32-0)
cas spécial.setnz al
.(Voir également la réponse du code machine de 32 bits de Daniel Schepler basée sur cela, qui a ensuite évolué pour utiliser d'autres idées que nous avions. J'inclus ma dernière version de cela au bas de cette réponse.)
Renvoie ZF = 0 pour l'hôte qui n'est pas dans le sous-réseau, ZF = 1 pour dans le sous-réseau, afin que vous puissiez vous connecter au résultat avec
je host_matches_subnet
Appelable avec la convention d'appel System V x86-64 comme
bool not_in_subnet(int dummy_rdi, const char *input_rsi);
si vous ajoutiezsetnz al
.La chaîne d'entrée contient à la fois l'hôte et le réseau, séparés par exactement 1 caractère non numérique. La mémoire suivant la fin de la largeur CIDR doit contenir au moins 3 octets non numériques avant la fin d'une page. (Cela ne devrait pas être un problème dans la plupart des cas, comme pour un argument cmdline.) La version 32 bits de Daniel n'a pas cette limitation.
Nous exécutons la même boucle d'analyse quadruple en pointillé 3 fois, obtenant les deux adresses IPv4 et obtenant le
/mask
sous forme d'entier dans l'octet haut d'un dword. (C'est pourquoi il doit y avoir une mémoire lisible après le/mask
, mais peu importe s'il y a des chiffres ASCII.)Nous faisons
(host ^ subnet) >> (32-mask)
pour décaler les bits d'hôte (ceux autorisés à ne pas correspondre), ne laissant que la différence entre le sous-réseau et l'hôte. Pour résoudre le/0
cas spécial où nous devons décaler de 32, nous sautons par-dessus le décalage sur count = 0. (neg cl
définit ZF, que nous pouvons ramifier et laisser comme valeur de retour si nous ne décalons pas.) Notez que32-mask mod 32 = -mask
, et les décalages scalaires x86 masquent leur nombre par& 31
ou& 63
.(non mis à jour avec la dernière version) Essayez-le en ligne!
y compris un
_start
qui l'appelleargv[1]
et renvoie un état de sortie.Cela fonctionne très bien si vous passez un argument de ligne de commande contenant une nouvelle ligne au lieu d'un espace. Mais ce doit être à la place , pas aussi bien.
Fonction de code machine x86 32 bits, 38 octets
Faites 9 entiers -> uint8_t analyse et "poussez-les" sur la pile, où nous les supprimons comme dwords ou utilisons le dernier encore dans CL. Évite la lecture après la fin de la chaîne.
En outre,
dec
n'est que de 1 octet en mode 32 bits.Appelant de test
la source
cmp/jcc
que vous avez mentionné, vous avez fait quelque chose commexor edx,edx;neg cl;cmovz eax,edx;shr eax,cl
- ou peut-être que vous avez déjà une valeur 0 quelque part. (Et puis vous n'auriez pas besoin de l'sub cl,32
instruction.)edi
devrait être égal à 0 lorsque la boucle se termine, donc celaxor eax,edx;neg cl;cmovz eax,edi;shr eax,cl
devrait fonctionner.cmove eax,edi
a 3 octets, ce qui est un lavage sur le supprimé,sub cl,32
puisshr cl,eax
enregistre un octet surshr cl,rax
et 32 bitsdec edi
enregistre un octet sur 64 bitsdec edi
. Mon assemblage donne alors.byte 0x33
(dans la syntaxe GNU binutils) = 51 pourin_subnet.size
.shr eax,cl
, par rapportshr %cl, %eax
à la syntaxe AT&T, votre dernier commentaire a inversé cela.) C'est une corvée de mettre à jour les réponses du code machine (et de porter l'_start
appelant et de décrire la convention d'appel pour le mode 32 bits.) .), donc je pourrais ne pas y arriver. Se sentir paresseux aujourd'hui. >. <edi
écriture, écrire la sortie, etc., il a fini par économiser 2 octets en net. (Au moins une fois, je me suis rendu compte qu'ilpush ecx;push ecx;push ecx
était plus court quesub esp,12
; et cela semblait être un lavage si je prédécrémentaisedi
et utilisaisstd;stosb;cld
ou si je stockais juste en utilisantdec edi;mov [edi],al
.Gelée , 23 octets
Essayez-le en ligne!
Lien monadique qui prend une adresse et un sous-réseau séparés par une barre oblique et renvoie 1 pour vrai et 0 pour faux.
Merci à @gwaugh d'avoir signalé une faille dans l'original - cela n'a pas permis de s'assurer que la liste binaire était longue de 32.
la source
Perl 5
-Mbigint -MSocket=:all -p
, 72 octetsEssayez-le en ligne!
la source
05AB1E , 21 octets
Prend le sous-réseau avant l'adresse.
Essayez-le en ligne ou vérifiez tous les cas de test .
Explication:
la source
R 120 octets
une fonction - j'ai collé ".32" au premier terme
w=function(a,b){f=function(x)as.double(el(strsplit(x,"[./]")));t=f(paste0(a,".32"))-f(b);sum(t[-5]*c(256^(3:0)))<2^t[5]}
et juste pour le plaisir:
require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]
qui est de 56 octets
la source
PHP ,
7573, 71 octetsUne fourchette de la réponse de @Luis felipe De jesus Munoz , en tant que standalone prenant une entrée des arguments de la ligne de commande. Sorties
'1'
pour Truthy,''
(chaîne vide) pour Fasley.Essayez-le en ligne!
-2 octets empruntant la petite astuce de @Christoph pour
strtok()
. Mais sa réponse est encore plus courte!la source
fonction d'assemblage x86,
4943 octetsCeci est principalement affiché pour satisfaire la demande de Peter Cordes pour la version révisée que j'ai créée. Il peut probablement disparaître une fois / s'il l'intègre dans sa réponse.
Cette fonction s'attend
esi
à pointer vers une chaîne d'entrée, avec les parties d'adresse et de sous-réseau séparées par un espace ou un caractère de nouvelle ligne, et la valeur de retour est dans l'indicateur ZF (qui, par définition, n'a que deux valeurs possibles).Et la partie wrapper Linux x86:
-6 octets en raison de la suggestion de Peter Cordes de renvoyer la valeur en ZF.
la source
xor edx,edx
et en le remplaçantcmovz eax,edx
parjz .nonzero; xor eax,eax; .nonzero:
.cmovz
gagne toujours si nous avons la convention d'appelebx=0
.jz
surshr
le setz ou le ret? Nous pouvons échanger lesetnz
tosetz
et revenir1
pour un match si cela vous aide. Ou même dire que notre valeur de retour est ZF. J'aurais dû le faire dans ma réponse. (Mais je ne pense pas que nous puissions justifier d'obliger l'appelant à créer des constantes pour nous, commeebx=0
. Ma réponse sur les astuces pour jouer au golf dans le code machine x86 / x64 soutient que ce serait étirer une convention d'appel personnalisée trop loin.cut
pour supprimer certaines colonnes de la sortie liste MSNA parce que toutes mes instructions sont courtes:nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-
. En outre, j'ai utilisé mov au lieu de movzx dans mon_start
appelant car le statut de sortie provient de l'octet de poids faible de l'argument verssys_exit()
. Le noyau ignore les octets supérieurs.setnz al
aprèscall in_subnet
dans le wrapper.call
/je
, plutôt que d'imprimer ou de transmettre le résultat. Comme je l'ai souligné dans les "astuces", certaines conventions d'appels d'appels système le font déjà dans la vie réelle (généralement avec CF = erreur).Java
215211207202200199198190180180octetsSorties
true
pour véridique etfalse
pour fausse.Remarque: Cela utilise
long
au lieu deint
pour le décalage à droite potentiel de 32.Essayez-le en ligne!
1 octet sauvé grâce au plafond
10 octets enregistrés grâce à Peter Cordes
la source
host ^ net
pour décaler les bits que vous souhaitez supprimer, au lieu de créer réellement un masque. Mais je suppose que Java a besoin d'une comparaison pour créer un booléen à partir d'un entier. Peut-être un!
, car peu importe le vrai ou le faux que vous produisez pour quelle sortie. (J'ai demandé au PO des éclaircissements pour savoir s'il avait l'intention d'exclure 0 / non nul, et il a répondu oui, il était conscient des conséquences de cette formulation:long
me fait perdre quelques octets, mais je compense cela en étant capable de supprimer le ternaire et de faire le XOR comme vous le suggérez. Je vérifie quoi d'autre je peux jouer au golf avant de posterFusain , 36 octets
Essayez-le en ligne! Le lien est vers la version détaillée du code. Prend le sous-réseau comme premier paramètre et
-
ne sort que si l'adresse se trouve dans le sous-réseau. Explication:Divisez le sous-réseau
/
.Retirez le masque et transformez-le en entier.
Envoyez l'adresse au tableau.
Divisez les deux adresses
.
, convertissez-les en nombres entiers, interprétez-les comme base 256 et supprimez les bits masqués.Comparez les deux valeurs.
la source
Japt , 26 octets
Essayez-le
-3 octets grâce à @Shaggy!
L'entrée est un tableau à 2 éléments
[address, subnet]
. Transposé JS ci-dessous:la source
++
.g
méthode me dérange; ne peut pas du tout trouver un moyen de le contourner. Au moins pas un qui vous fera économiser un octet.C # (Visual C # Interactive Compiler) , 187 octets
Je peux définitivement jouer au golf plus bas.
Essayez-le en ligne!
la source
C # (Visual C # Interactive Compiler) , 134 octets
Essayez-le en ligne!
Instruction LINQ qui prend un tableau de chaînes à 2 éléments en entrée dans
[address, subnet]
format.Chaque quadruple pointillé est converti en 32 bits de long en utilisant la manipulation de bits. Les bits sont décalés vers la droite de la taille du sous-réseau et les éléments sont comparés pour l'égalité.
Il y avait quelques réponses C # au moment où cette réponse a été publiée, mais aucune qui utilisait de la manipulation de bits purs.
la source
Rubis (48 octets)
la source
====