Ich bin in Ihren Subnetzen und spiele Ihren Code

17

Herausforderung

Bestimmen Sie bei einem IPv4 addressin Punkt-Vierfach-Notation und einem IPv4 subnetin CIDR-Notation , ob das addressin der Liste steht subnet. Geben Sie einen eindeutigen und konsistenten Wert aus, wenn er sich im befindet subnet, und einen eindeutigen und konsistenten Wert, wenn er sich nicht im befindet subnet. Die Ausgabewerte müssen in Ihrer Sprache nicht unbedingt wahr oder falsch sein.

Kurze Einführung in die CIDR-Subnetznotation

IPv4-Netzwerkadressen haben eine Länge von 32 Bit und sind zur Erleichterung des Lesens in vier Gruppen zu je 8 Bit unterteilt. Die CIDR-Subnetznotation ist eine Maske mit der angegebenen Anzahl von Bits, beginnend ganz links. Für ein /24Subnetz bedeutet dies beispielsweise, dass die am weitesten rechts stehenden 8 Bits der Adresse in diesem Subnetz verfügbar sind. Somit befinden sich zwei Adressen, die durch höchstens getrennt 255sind und dieselbe Subnetzmaske aufweisen, im selben Subnetz. Beachten Sie, dass bei einem gültigen CIDR alle Host-Bits (auf der rechten Seite) nicht gesetzt (Nullen) sind.

xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^---    subnet mask   ---^ ^-hosts-^

In einem anderen Beispiel gibt ein /32Subnetz an, dass alle Bits die Subnetzmaske sind, was im Wesentlichen bedeutet, dass pro Host nur ein Host zulässig ist /32.

xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^---        subnet mask        ---^

Beispiele:

Verwenden Sie Truefür "im Subnetz" und Falsefür "nicht im Subnetz" als Ausgabe:

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

Regeln und Erläuterungen

  • Da das Parsen von Eingaben nicht der interessante Punkt dieser Herausforderung ist, erhalten Sie garantiert gültige IPv4-Adressen und Subnetzmasken.
  • Die Ein- und Ausgabe kann auf jede bequeme Weise erfolgen .
  • Sie können das Ergebnis an STDOUT drucken oder als Funktionsergebnis zurückgeben. Bitte geben Sie bei Ihrer Übermittlung an, welche Werte die Ausgabe annehmen kann.
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.
AdmBorkBork
quelle
Müssen wir Eingaben im selben Format wie Ihre Testfälle vornehmen?
Verkörperung der Unwissenheit
1
@EmbodimentofIgnorance Sie müssen sie nicht wie in den Beispielen als eine Zeile pro Zeile verwenden, sondern Sie müssen sie wie in den Beispielen als gepunktetes Vierer- und gepunktetes Teilnetz verwenden. (Siehe zB die JavaScript-Antwort von Arnauld)
AdmBorkBork
Ist es in Ordnung, sie durch einen Schrägstrich zu trennen, z 10.0.0.1/10.0.0.0”/16. B. ?
Nick Kennedy
1
@Poke Ich stimme Ihnen zu, dass die CIDR-Notation eine IP-Adresse und eine Subnetzgröße beschreibt. Wie in 1.255.1.1/8ist ein gültiger CIDR- Ausdruck , der den Host 1.255.1.1innerhalb des Netzwerks 1.0.0.0mit einer Subnetzmaske von darstellt 255.0.0.0. Allerdings fordert die Herausforderung für die Netzwerknummer und Subnetz speziell in CIDR - Notation, die 1.255.1.1/8keine gültige Netzwerknummer und Subnet - Kombination ist.
2.
1
Jetzt brauchen wir auch eine IPv6-Version dieser Herausforderung
Ferrybig

Antworten:

13

Python 3 (62 Bytes)

Sehr einfach:

from ipaddress import*
lambda i,m:ip_address(i)in ip_network(m)
wie auch immer
quelle
9
Schön, aber hat Python auch eine eingebaute Funktion zum Erkennen von Ziegen ?
Benjamin Urquhart
3
Natürlich ist in Mathematica alles integriert - auch für Exoplaneten ! Nichts kann das übertreffen ... Aber wie Sie gesehen haben könnten, entspricht Python Mathematicas Ziegengestalt
bis
Ich frage mich, ob ein ip_adressObjekt und ein ip_networkObjekt any convenient methodPython gewinnen lassen, es sei denn, eine Python-basierte Golfsprache hat diese als Typ.
Mein Pronomen ist monicareinstate
Sie werden es in normalem Python nicht im Bereich von 20 Bytes bekommen. Lediglich der Import und Lambda sind schon länger als die Stax-Antwort. Es ist keine Überraschung , dass Golf - Sprachen von „normalen“ Sprachen gewinnen ... :-(
agtoever
@someone: Ich schlug Python mit 53 Byte von x86-64 Maschinencode . :) Nicht ein traditionelles Golf Sprache, und die meisten der Code-Größe ist Parsing Saiten-> int manuell. (host^net)>>(32-mask)ist nur 10 Bytes. Bei Aufgaben, die keine Listen enthalten, oder bei denen eine Funktion auf eine Liste abgebildet wird, liegt die Zeit jedoch in der Mitte, da viele skalare Operationen mit einem 2- oder 3-Byte-Befehl ausgeführt werden können und Schleifen innerhalb weniger Bytes erstellt werden können.
Peter Cordes
4

C # (Visual C # -Compiler) , 250 + 31 = 281 Byte

(a,b)=>{Func<string,string>h=g=>string.Join("",g.Split('.').Select(x=>{var e=Convert.ToString(int.Parse(x),2);while(e.Length<8)e='0'+e;return e;}));a=h(a);var c=b.Split('/');b=h(c[0]);var d=int.Parse(c[1]);return a.Substring(0,d)==b.Substring(0,d);};

Bytecount enthält using System;using System.Linq;

Probieren Sie es online!

Ich schrieb dies in JS, sobald die Herausforderung veröffentlicht wurde, aber Arnauld schlug mich mit einer viel besseren Antwort, also hier ist es stattdessen in C #.

Auf jeden Fall viel Platz zum Golfen.

Erläuterung:

Die Funktion besteht aus einer Unterfunktion mit dem Namen h:

h=g=>string.Join("",
    g.Split('.').Select(x => {
        var e = Convert.ToString(int.Parse(x), 2);
        while (e.Length < 8) e = '0' + e;
        return e;
    }
);

Diese Unterfunktion teilt die IP-Adresse auf ., konvertiert jede Zahl in eine Binärzeichenfolge, füllt jede Zeichenfolge mit einem Links-Pad mit 0einer Länge von 8 Bit und verknüpft die Zeichenfolgen dann zu einer 32-Bit-Binärzeichenfolge.

Dies erfolgt sofort an Ort und Stelle mit a=h(a);der angegebenen IP-Adresse.
Anschließend teilen wir die Subnetzmaske in eine IP-Adresse und eine Maskennummer mit aufc=b.Split('/');

Die IP-Adressenkomponente wird auch durch unsere Unterfunktion übergeben: b=h(c[0]);und die Maskennummer wird in eine Ganzzahl umgewandelt:var d=int.Parse(c[1]);

Schließlich nehmen wir die ersten dBits beider Binärzeichenfolgen (wobei ddie Maskennummer ist) und vergleichen sie:return a.Substring(0,d)==b.Substring(0,d);

Skidsdev
quelle
1
Zu müde, um das zu klären
Abgelaufene Daten
1
PadLeft auch dabei vergessen Online
Abgelaufene Daten
Viele Optimierungen. Ich freue mich, Ihnen mitteilen zu können, dass Ihre rPadSaiten bereits eingebaut sind. Pastebin-Link zu TIO-Link, der zu lang ist
mein Pronomen ist monicareinstate
2
@someone Small FYI: URL- Kürzungen wie tinyurl.com sind im Gegensatz zu den meisten anderen in Kommentaren zu dieser SE zulässig. :)
Kevin Cruijssen
1
188 - tinyurl.com/y6xfkbxt - nette Tipps zur URL-Verkürzung @KevinCruijssen
dana
4

Linux POSIX-Shell (mit net-tools / iputils) (34 Bytes nicht terminierend, 47 Bytes terminierend)

Was eignet sich am besten zum Analysieren von Netzwerkmasken und -adressen als die Netzwerkdienstprogramme selbst? :)

route add -net $2 reject;! ping $1

Warnung: Das Skript kann möglicherweise Ihre Internetverbindung beschädigen. Führen Sie es mit Sorgfalt aus.

Eingabe: Das Skript verwendet die getestete IP-Adresse als erstes Argument und das getestete Subnetz. als zweites Argument.

Ausgabe: Das Skript gibt einen Wahrheitswert (0) zurück, wenn das erste Argument des Skripts zu dem im zweiten Argument angegebenen Subnetz gehört. Andernfalls wird es niemals beendet.

Annahmen: Das Skript muss als Root-Benutzer in einer sauberen Umgebung ausgeführt werden ( dh , der Administrator hat keine andere Blackhole-Route festgelegt, und wenn eine vorherige Instanz des Skripts ausgeführt wurde, wurde die von ihm erstellte Blackhole-Route entfernt ). Das Skript geht auch von einer "funktionierenden Internetverbindung" aus ( dh es liegt eine gültige Standardroute vor).


Erläuterung:

Wir erstellen eine Blackhole- Route zum angegebenen Subnetz. Anschließend testen wir die Konnektivität zur angegebenen IP-Adresse mithilfe von Ping . Wenn die Adresse nicht zum Subnetz gehört (und eine ordnungsgemäß eingerichtete Internetverbindung vorausgesetzt wird ), versucht Ping , Pakete an diese Adresse zu senden. Beachten Sie, dass es keine Rolle spielt, ob diese Adresse tatsächlich antwortet, da Ping es für immer versucht. Wenn die Adresse zum Subnetz gehört, schlägt der Ping mit ENETUNREACH fehl und gibt 2 zurück. Da wir den Befehl negiert haben, ist das Skript erfolgreich.


Beispiel

Prüfen Sie, ob 5.5.5.5 zu 8.8.8.0/24 gehört

$ sudo ./a.sh 5.5.5.5 8.8.8.0/24
PING 5.5.5.5 (5.5.5.5) 56(84) bytes of data.
[...runs forever...]

(Reinigen Sie mit, sudo ip route del 8.8.8.0/24nachdem Sie den Befehl ausgeführt haben).

Testen Sie, ob 5.5.5.5 zu 5.5.5.0/24 gehört:

$ sudo ./a.sh 5.5.5.5 5.5.5.0/24
connect: Network is unreachable
$ echo $?
0

(Reinigen Sie mit, sudo ip route del 5.5.5.0/24nachdem Sie den Befehl ausgeführt haben).

Testen Sie, ob 8.8.8.8 zu 5.5.5.0/24 gehört:

$ sudo ./a.sh 8.8.8.8 5.5.5.0/24
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=122 time=2.27 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=122 time=1.95 ms
[...runs forever...]

(Reinigen Sie mit, sudo ip route del 5.5.5.0/24nachdem Sie den Befehl ausgeführt haben).


47-Byte-Version, wenn nicht terminierende Skripte nicht zulässig sind

route add -net $2 reject;ping -c1 $1;[ $? = 2 ]

Laut @ Grimys Kommentar ist hier die Version, die immer endet und 0 (wahr) zurückgibt, wenn sich die Adresse im Subnetz befindet, und 1 (falsch), wenn dies nicht der Fall ist. Wir lassen Ping mit dem -c1Flag enden, das die Anzahl der gesendeten Pakete auf 1 begrenzt. Wenn die Adresse geantwortet hat, gibt Ping 0 zurück, und wenn nicht, gibt Ping 1 zurück. Nur wenn die Adresse zum Blackholed-Subnetz gehört, gibt Ping 2 zurück. Daran testen wir also im letzten Befehl.

yoann
quelle
3
Obwohl clever, erfüllt dies nicht die Anforderung, einen eindeutigen und konsistenten Wert auszugeben, wenn sich die Adresse nicht im Subnetz befindet ( ewig ausgeführt zählt nicht als Ausgabe , siehe auch dies ).
Grimmy
1
@Grimy: Aber es läuft nicht für immer still , so dass nur Ihr 2. Link gilt, nicht der erste. Ich denke pingauch, dass SIGPIPE sterben würde, wenn es mit stdout + stderr in einem anderen Programm laufen würde und der Leser die Pipe schloss. Und das ist der wahrscheinlichste Anwendungsfall, da der Beendigungsstatus in beiden Fällen erfolgreich sein kann (wenn wir eine -c1Option zum Ping hinzugefügt haben , um die Anzahl festzulegen). Aber sicher, das Lesen der Ausgabe mit var=$(/a.sh)würde fehlschlagen. Sie brauchen einen Leser, der nach der Entscheidung stehen bleibt, anstatt die gesamte Ausgabe zu lesen und sie sich dann anzusehen.
Peter Cordes
@Grimy Fair point (obwohl ich der Argumentation zuliebe sagen könnte, dass wir hier zwei konsistente Werte haben, da pingdiese bei einer Blackholed-Adresse in weniger als einer Sekunde enden werden). Ich habe eine abschließende Version für zusätzliche 13 Bytes hinzugefügt! :)
yoann
3

JavaScript (ES6), 82 Byte

Übernimmt die Eingabe als (address)(subnet). Gibt einen Booleschen Wert zurück.

a=>s=>!([s,v]=s.split`/`,+v&&(g=s=>s.split`.`.map(k=v=>k=k<<8|v)|k>>32-v)(a)^g(s))

Probieren Sie es online!

Arnauld
quelle
3

PHP , 101 92 88 Bytes

-13 Bytes von @gwaugh

function($i,$r){[$r,$n]=explode('/',$r);return(ip2long($i)&~(1<<32-$n)+1)==ip2long($r);}

Probieren Sie es online!

Luis Felipe De Jesus Munoz
quelle
2
Hatte ein function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
Christoph
@Christoph sehr schön! Mir ist nie in den Sinn gekommen, dass Sie nur ein Token für den zweiten Anruf verwenden können strtok(). Ihre ist 4 Bytes kürzer als meine sehr ähnliche Antwort unten. Requisiten!
2.
@Christoph Du solltest deine Lösung als separate Antwort posten, da sie besser ist als meine.
Luis Felipe De Jesus Munoz
3

PowerPC / PPC64 C, 116 114 Bytes

#include<stdio.h>
main(){unsigned u[4];char*p=u;for(;p<u+3;)scanf("%hhu%c",p++,u+3);return!((*u^u[1])>>32-p[-4]);}

(Getestet unter x86_64 Ubuntu 18.04 mit powerpc64-linux-gnu-gcc -static und qemu-user.)

Das Programm nimmt die beiden Zeilen bei der Standardeingabe und gibt als Exit-Code 1 zurück, wenn die Adresse übereinstimmt, und 0, wenn dies nicht der Fall ist. (Dies hängt also von der Spezifikation ab, die keinen Wahrheitswert für eine Übereinstimmung und keinen Falschwert für eine Nichtübereinstimmung erfordert.) Beachten Sie, dass Sie bei interaktiver Ausführung ^Dnach Eingabe der zweiten Zeile dreimal EOF ( ) signalisieren müssen .

Dies setzt voraus, dass PowerPC ein Big-Endian ist und dass diese Plattform 0 zurückgibt, um einen vorzeichenlosen 32-Bit-Wert um 32 nach rechts zu verschieben. Dabei werden die Oktette einzeln in vorzeichenlose Werte eingelesen, zusammen mit der Netzmaskenlänge in einem anderen Byte ; dann nimmt es das xor der beiden vorzeichenlosen 32-Bit-Adressen und verschiebt die irrelevanten Bits heraus. Schließlich gilt !es, die Anforderung zu erfüllen, nur zwei unterschiedliche Werte zurückzugeben.

Hinweis: Es könnte möglich sein , zwei Bytes abrasieren durch Ersetzen u+3mit pund erfordern Kompilierung mit -O0. Das ist allerdings gefährlicher, als es mir wichtig ist.

Vielen Dank an Peter Cordes für die Inspiration für diese Lösung.


Portableres C, 186 171 167 Bytes

Hier behalte ich eine portablere Version bei, die 167 Byte lang ist.

#include<stdio.h>
main(){unsigned a,b,c,d,e,f,g,h,n;scanf("%u.%u.%u.%u %u.%u.%u.%u/%u",&a,&b,&c,&d,&e,&f,&g,&h,&n);return!(n&&((((a^e)<<8|b^f)<<8|c^g)<<8|d^h)>>32-n);}

Dieses Programm nimmt die beiden Zeilen der Standardeingabe und gibt den Exit-Code 1 zurück, wenn sich die Adresse im Subnetz befindet, und 0, wenn dies nicht der Fall ist. (Dies hängt also von der Spezifikation ab, dass für Übereinstimmungen kein Wahrheitswert und für Nichtübereinstimmungen ein Falschwert erforderlich ist.)

Eine Aufschlüsselung des Kernausdrucks:

  • a^e, b^f, c^g, d^hBerechnet die xor der Adresse und die Maske Byte- für -Byte.
  • (((a^e)<<8|b^f)<<8|c^g)<<8|d^h kombiniert sie dann nach einer Horner-ähnlichen Methode zu einem einzelnen vorzeichenlosen 32-Bit-Wert.
  • ...>>32-nverschiebt dann die Bits der xor-Differenz, die für die Subnetzmaske nicht relevant sind (wobei zu beachten ist, dass -C eine höhere Priorität hat als <<)
  • Es gibt jedoch einen Fall: Wenn n = 0 ist, ~0U<<32wird ein undefiniertes Verhalten ausgegeben, vorausgesetzt, unsignedes sind 32 Bit (was auf praktisch allen aktuellen Plattformen der Fall ist). Wenn andererseits n = 0 ist n&&..., stimmt jede Adresse überein, sodass das richtige Ergebnis erzielt wird (unter Ausnutzung des Kurzschlussverhaltens von &&).
  • Um die Anforderung zu erfüllen, dass der Ausgang nur einer von zwei Werten sein kann, wenden wir !den Ausgang 0 oder 1 an.

-15 Byte aufgrund von Kommentaren von ceilingcat und AdmBorkBork

-4 Bytes aufgrund eines Kommentars von Peter Cordes

Daniel Schepler
quelle
1
Die Verwendung von Exit-Codes zur Rückgabe von Werten ist eine der Standard-E / A-Methoden und daher zulässig.
AdmBorkBork
@ceilingcat Natürlich, wie dumm von mir, das zu verpassen.
Daniel Schepler
@AdmBorkBork OK, danke, ich habe es geändert, um Exit-Code zu verwenden.
Daniel Schepler
Idee: Ziel ist eine Little-Endian- oder Big-Endian-C-Implementierung (für Code-Golf ist kein portabler Code erforderlich) und Ausgabezeiger mit Wortspielen auf die Bytes von unsigned. zB mit char*p=&athen p++,p++,p++,...oder p--,...als scanf args. Die Formatzeichenfolge müsste "%hhu.%hhu..."allerdings so sein , dass es ein bedeutender Kompromiss zwischen dieser zusätzlichen Größe und der Angabe weniger Variablen und der Möglichkeit ist, dies zu tun(a^b)>>(32-count)
Peter Cordes,
1
@PeterCordes Ja, die richtige Schicht funktioniert, danke.
Daniel Schepler
2

Stax , 22 Bytes

é.○▄╗jF⌐§╥§I╓☻lw«ç┴║╫┼

Führen Sie es aus und debuggen Sie es

Die Eingabeparameter werden bei der Standardeingabe durch Leerzeichen getrennt.

Ausgepackt, ungolfed und kommentiert sieht es so aus.

'/:/~       split on slash and push the last group back to the input stack
j{          split on space; for each group, run this code block
  './       split on period
  {emVB|E   evaluate integers and decode integer as base-256
  ;e|<      peek from input stack and shift left
  Vu/       integer divide by 2^32
F           end of for-each
=           two values left on stack are equal?

Führen Sie dieses aus

rekursiv
quelle
2

x86-64-Maschinencodefunktion, 53 48 Bytes

Änderungsprotokoll:

  • -2 jzüber die Verschiebung, anstatt eine 64-Bit-Verschiebung zu verwenden, um den >>(32-0)Sonderfall zu behandeln .
  • -3 kehre in ZF statt AL zurück und spare 3 Bytes für a setnz al.

(Siehe auch die darauf basierende 32-Bit-Maschinencode-Antwort von Daniel Schepler , die sich dann weiterentwickelte, um einige andere Ideen zu verwenden, die wir hatten. Ich füge meine neueste Version davon am Ende dieser Antwort hinzu.)


Gibt ZF = 0 für den Host zurück, der sich nicht im Subnetz befindet, und ZF = 1 für den Host im Subnetz, sodass Sie mit auf das Ergebnis verzweigen könnenje host_matches_subnet

Aufrufbar mit der x86-64-System-V-Aufrufkonvention, als
bool not_in_subnet(int dummy_rdi, const char *input_rsi);ob Sie hinzufügen setnz al.

Die Eingabezeichenfolge enthält sowohl den Host als auch das Netzwerk, getrennt durch genau 1 nichtstelliges Zeichen. Der Speicher nach dem Ende der CIDR-Breite muss vor dem Ende einer Seite mindestens 3 nicht-stellige Bytes enthalten. (Sollte in den meisten Fällen kein Problem sein, wie bei einem Cmdline-Argument.) Daniels 32-Bit-Version hat diese Einschränkung nicht.

Wir führen dieselbe gepunktete Quad-Parse-Schleife dreimal aus, ermitteln die beiden IPv4-Adressen und ermitteln die /maskGanzzahl im High-Byte eines Dwords. (Aus diesem Grund muss nach dem ein lesbarer Speicher vorhanden sein /mask, aber es spielt keine Rolle, ob ASCII-Ziffern vorhanden sind.)

Wir (host ^ subnet) >> (32-mask)verschieben die Host-Bits (die nicht übereinstimmen dürfen), sodass nur der Unterschied zwischen dem Subnetz und dem Host übrig bleibt. Um den /0speziellen Fall zu lösen , dass wir um 32 verschieben müssen, überspringen wir die Verschiebung bei count = 0. ( neg clLegt ZF fest, auf das verzweigt und der Rückgabewert verwendet werden kann, wenn keine Verschiebung erfolgt.) Beachten Sie, dass bei 32-mask mod 32 = -maskx86-Skalarverschiebungen die Anzahl durch & 31oder maskiert wird & 63.

    line  addr   machine                NASM source.  (from nasm -felf64 -l/dev/stdout)
    num          code bytes

     1                             %use smartalign
     2                             
     3                                 ;10.4.1.33 10.4.0.0/23         true
     4                                 ;10.4.1.33 10.4.0.0/24         false
     5                             
     6                             ;; /codegolf/185005/im-in-your-subnets-golfing-your-code
     7                             %ifidn __OUTPUT_FORMAT__, elf64
     8                             in_subnet:
     9                             
    10 00000000 6A03                   push 3
    11 00000002 5F                     pop  rdi                    ; edi = 3 dotted-quads to parse, sort of.
    12                             .parseloop:
    13                             
    14                                 ;xor  ebx,ebx             ; doesn't need to be zeroed first; we end up shifting out the original contents
    15                                 ;lea  ecx, [rbx+4]
    16 00000003 6A04                   push   4
    17 00000005 59                     pop    rcx                  ; rcx = 4 integers in a dotted-quad
    18                             .quadloop:
    19                             
    20 00000006 31D2                   xor   edx,edx               ; standard edx=atoi(rdi) loop terminated by a non-digit char
    21 00000008 EB05                   jmp  .digit_entry
    22                              .digitloop:
    23 0000000A 6BD20A                 imul   edx, 10
    24 0000000D 00C2                   add    dl, al
    25                              .digit_entry:
    26 0000000F AC                     lodsb
    27 00000010 2C30                   sub    al, '0'
    28 00000012 3C09                   cmp    al, 9
    29 00000014 76F4                   jbe   .digitloop
    30                                 ; al=non-digit character - '0'
    31                                 ; RDI pointing to the next character.
    32                                 ; EDX = integer
    33                             
    34 00000016 C1E308                 shl    ebx, 8
    35 00000019 88D3                   mov    bl, dl               ; build a quad 1 byte at a time, ending with the lowest byte
    36 0000001B E2E9                   loop .quadloop
    37                             
    38 0000001D 53                     push   rbx          ; push result to be collected after parsing 3 times
    39 0000001E FFCF                   dec    edi
    40 00000020 75E1                   jnz   .parseloop
    41                             
    42 00000022 59                     pop    rcx   ; /mask  (at the top of a dword)
    43 00000023 5A                     pop    rdx   ; subnet
    44 00000024 58                     pop    rax   ; host
    45 00000025 0FC9                   bswap  ecx   ; cl=network bits  (reusing the quad parse loop left it in the high byte)

    49 00000027 F6D9                   neg    cl
    50 00000029 7404                   jz   .all_net     ; skip the count=32 special case
    51                             
    52 0000002B 31D0                   xor    eax, edx   ; host ^ subnet
    53 0000002D D3E8                   shr    eax, cl    ; shift out the host bits, keeping only the diff of subnet bits
    54                             
    55                             .all_net:
    56                                ; setnz  al         ; return ZF=1 match,  ZF=0 not in subnet
    57 0000002F C3                     ret
    58 00000030 30                 .size:      db $ - in_subnet

              0x30 = 48 bytes

(nicht mit der neuesten Version aktualisiert) Probieren Sie es online!

Einschließlich eines _start, der es aufruft argv[1]und einen Beendigungsstatus zurückgibt.

## on my desktop
$ ./ipv4-subnet "10.4.1.33 10.4.0.0/24"    && echo "$? : in subnet" || echo "$? : not in subnet"
not in subnet

$ ./ipv4-subnet "10.4.1.33 10.4.0.0/23"    && echo "$? : in subnet" || echo "$? : not in subnet"
in subnet

Es funktioniert einwandfrei, wenn Sie ein Befehlszeilenargument übergeben, das eine neue Zeile anstelle eines Leerzeichens enthält. Aber es muss stattdessen nicht so gut sein.


x86 32-Bit-Maschinencodefunktion, 38 Byte

Führe 9 Integer -> uint8_t-Parser aus und "push" sie auf den Stack, wo wir sie als Dwords ablegen oder den letzten, der noch in CL enthalten ist. Vermeidet es, über das Ende der Zeichenkette hinaus zu lesen.

Ist auch decnur 1 Byte im 32-Bit-Modus.

    72                             in_subnet:
    73 00000000 89E7                   mov   edi, esp
    74 00000002 51                     push  ecx
    75 00000003 51                     push  ecx                   ; sub esp,8
    76                             .byteloop:
    77                             
    78 00000004 31C9                   xor   ecx,ecx               ; standard ecx=atoi(rdi) loop terminated by a non-digit char
    79                                                             ; runs 9 times: 8 in two dotted-quads, 1 mask length
    80 00000006 EB05                   jmp  .digit_entry
    81                              .digitloop:
    82 00000008 6BC90A                 imul   ecx, 10
    83 0000000B 00C1                   add    cl, al
    84                              .digit_entry:
    85 0000000D AC                     lodsb
    86 0000000E 2C30                   sub    al, '0'
    87 00000010 3C09                   cmp    al, 9
    88 00000012 76F4                   jbe   .digitloop
    89                                 ; RDI pointing to the next character.
    90                                 ; EDX = integer
    91                             
    92 00000014 4F                     dec    edi
    93 00000015 880F                   mov    [edi], cl           ; /mask store goes below ESP but we don't reload it
    94 00000017 39E7                   cmp    edi, esp
    95 00000019 73E9                   jae   .byteloop
    96                             
    97                                 ;; CL = /mask still there from the last conversion
    98                                 ;; ESP pointing at subnet and host on the stack, EDI = ESP-1
    99                             
   100 0000001B 5A                     pop    edx   ; subnet
   101 0000001C 58                     pop    eax   ; host
   102                             
   103 0000001D 31D0                   xor    eax, edx             ; host ^ subnet
   104 0000001F F6D9                   neg    cl                   ; -mask = (32-mask) mod 32;  x86 shifts mask their count
   105 00000021 7402                   jz     .end                 ; 32-n = 32 special case
   106 00000023 D3E8                   shr    eax, cl
   107                             .end:
   108                                 ; setz  al                  ; just return in ZF
   109 00000025 C3                     ret

   110 00000026 26                 .size:      db $ - in_subnet
      0x26 = 38 bytes

Anrufer testen

   113                             global _start
   114                             _start:
   115 00000027 8B742408               mov    esi, [esp+8]   ; argv[1]
   116 0000002B E8D0FFFFFF             call   in_subnet
   117 00000030 0F95C3                 setnz  bl
   118 00000033 B801000000             mov    eax, 1         ; _exit syscall
   119 00000038 CD80                   int    0x80
Peter Cordes
quelle
Ich bin gespannt, wie sich die 32-Bit-Asm-Byteanzahl entwickeln würde, wenn Sie statt der von cmp/jccIhnen erwähnten etwas wie xor edx,edx;neg cl;cmovz eax,edx;shr eax,cl- oder vielleicht haben Sie bereits irgendwo einen 0-Wert. (Und dann würden Sie die sub cl,32Anweisung nicht brauchen .)
Daniel Schepler
1
Yup, sieht aus wie edisollte 0 sein, wenn die Schleife beendet wird, xor eax,edx;neg cl;cmovz eax,edi;shr eax,clsollte also funktionieren.
Daniel Schepler
1
Wenn ich die Dinge richtig gezählt habe, cmove eax,edihat das 3 Bytes, was ein Überlauf über das entfernte ist, sub cl,32dann shr cl,eaxspart man ein Byte über shr cl,raxund 32-Bit dec edispart ein Byte über 64-Bit dec edi. Meine Assembly gibt dann .byte 0x33(in GNU-Binutils-Syntax) = 51 für in_subnet.size.
Daniel Schepler
Gute Idee, danke. (In Intel - Syntax ist es shr eax,cl, gegenüber shr %cl, %eaxin AT & T - Syntax, die letzte Bemerkung , dass umgekehrt.) Es ist ein bisschen mühsam zu aktualisieren Maschinencode - Antworten (und Port den _startAnrufer und neu beschreibt die Aufrufkonvention für 32-Bit - Modus .. .), also komme ich vielleicht nicht dran vorbei. Faul heute. >. <
Peter Cordes
1
Ich habe gerade versucht, den Kommentar zu implementieren, den Sie zu meiner Antwort über das Entfernen der Doppelschleife und das Speichern in Stapelvariablen gegeben haben - und sogar mit dem zusätzlichen Code zum Initialisieren des Schreibzeigers edi, Schreiben der Ausgabe usw. wurden 2 Bytes gespart im Netz. (Mindestens einmal wurde mir klar, dass push ecx;push ecx;push ecxes kürzer war als sub esp,12; und es schien eine Wäsche zu sein, ob ich vorab dekrementiert ediund verwendet habe std;stosb;cldoder ob ich nur mit aufbewahrt habe dec edi;mov [edi],al.
Daniel Schepler
1

Jelly , 23 Bytes

ṣ”/ṣ€”.Vḅ⁹s2+Ø%BḊ€ḣ€ʋ/E

Probieren Sie es online!

Monadischer Link, der die durch einen Schrägstrich getrennte Adresse und das Subnetz verwendet und 1 für wahr und 0 für falsch zurückgibt.

Vielen Dank an @gwaugh für den Hinweis auf einen Fehler im Original - es konnte nicht sichergestellt werden, dass die Binärliste 32 Zeichen lang ist.

Nick Kennedy
quelle
1

Perl 5 -Mbigint -MSocket=:all -p , 72 Bytes

sub c{unpack N,inet_aton pop}<>=~/(.*)\/(.*)/;$_=c($_)-&c($1)<2**(32-$2)

Probieren Sie es online!

Xcali
quelle
1

05AB1E , 21 Bytes

'/¡`U‚ε'.¡b8jð0:JX£}Ë

Übernimmt das Subnetz vor der Adresse.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

'/¡              '# Split the first subnet-input by "/"
   `              # Push both values separated to the stack
    U             # Pop and store the trailing number in variable `X`
                 # Pair the subnet-IP with the second address-input
     ε            # Map both to:
      '.¡        '#  Split on "."
         b        #  Convert each integer to binary
          8j      #  Add leading spaces to make them size 8
          ð0:     #  And replace those spaces with "0"
             J    #  Join the four parts together to a single string
              X£  #  And only leave the first `X` binary digits as substring
                # After the map: check if both mapped values are the same
                  # (which is output implicitly as result)
Kevin Cruijssen
quelle
1

R 120 Bytes

eine Funktion - Ich habe ".32" in das erste Glied eingefügt

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]}

und nur zum Spaß:

require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]

Das sind 56 Bytes

Zahiro Mor
quelle
1

PHP ,75 7371 Bytes

<?=strtok($argv[2],'/')==long2ip(ip2long($argv[1])&1+~1<<32-strtok(_));

Ein Auszug aus der Antwort von @Luis felipe De jesus Munoz als Standalone, der Eingaben von Kommandozeilenargumenten entgegennimmt. Ausgaben '1'für Truthy ''(leere Zeichenfolge) für Fasley.

$ php ipsn.php 127.0.0.1 127.0.0.0/24
1
$ php ipsn.php 127.1.2.3 127.0.0.0/24

Probieren Sie es online!

-2 Bytes, die @Christophs kleinen Trick für entlehnen strtok(). Seine Antwort ist allerdings noch kürzer!

640 KB
quelle
1

x86-Montagefunktion, 49 43 Bytes

Dies geschieht hauptsächlich, um die Anfrage von Peter Cordes nach der überarbeiteten Version, die ich erstellt habe, zu erfüllen. Es kann wahrscheinlich einmal verschwinden / wenn er es in seine Antwort aufnimmt.

Diese Funktion erwartet esi, auf eine Eingabezeichenfolge zu verweisen, wobei die Adress- und Subnetzteile entweder durch ein Leerzeichen oder ein Zeilenumbruchzeichen getrennt sind, und der Rückgabewert im ZF-Flag (das per Definition nur zwei mögliche Werte enthält).

 1                                  %use smartalign
 2                                  
 3                                      ;10.4.1.33 10.4.0.0/23         true
 4                                      ;10.4.1.33 10.4.0.0/24         false
 5                                  
 6                                  ;; /codegolf/185005/im-in-your-subnets-golfing-your-code
 7                                  in_subnet:
 8                                  
 9                                      ;xor  ebx,ebx             ; doesn't need to be zeroed first; we end up shifting out the original contents
10                                      ;lea  ecx, [rbx+4]
11 00000000 6A09                        push   9
12 00000002 59                          pop    ecx                  ; ecx = 9 integers (8 in two dotted-quads,
13                                                                  ; 1 mask length)
14                                  
15 00000003 89E7                        mov   edi, esp
16 00000005 83EC0C                      sub   esp, 12
17                                  .quadloop:
18                                  
19 00000008 31D2                        xor   edx,edx               ; standard edx=atoi(rdi) loop terminated by a non-digit char
20 0000000A EB05                        jmp  .digit_entry
21                                   .digitloop:
22 0000000C 6BD20A                      imul   edx, 10
23 0000000F 00C2                        add    dl, al
24                                   .digit_entry:
25 00000011 AC                          lodsb
26 00000012 2C30                        sub    al, '0'
27 00000014 3C09                        cmp    al, 9
28 00000016 76F4                        jbe   .digitloop
29                                      ; al=non-digit character - '0'
30                                      ; RDI pointing to the next character.
31                                      ; EDX = integer
32                                  
33 00000018 4F                          dec    edi
34 00000019 8817                        mov    [edi], dl
35 0000001B E2EB                        loop .quadloop
36                                  
37 0000001D 59                          pop    ecx   ; /mask  (at the top of a dword)
38 0000001E 5A                          pop    edx   ; subnet
39 0000001F 58                          pop    eax   ; host
40 00000020 0FC9                        bswap  ecx   ; cl=network bits  (reusing the quad parse loop left it in the high byte)
41                                  
42                                  ;    xor    cl, -32    ; I think there's some trick like this for 32-n or 31-n, but maybe only if we're masking to &31?  Then neg or not work.
43                                  
44 00000022 31D0                        xor    eax, edx   ; host ^ subnet
45                                  ;    xor    edx, edx   ; edx = 0
46 00000024 F6D9                        neg    cl
47 00000026 7402                        jz     .end
48 00000028 D3E8                        shr    eax, cl    ; count=32 special case isn't special for a 64-bit shift
49                                  .end:    
50 0000002A C3                          ret
51 0000002B 2B                      .size:      db $ - in_subnet

Und der x86 Linux Wrapper Teil:

53                                  global _start
54                                  _start:
55 0000002C 8B742408                    mov    esi, [esp+8]   ; argv[1]
56 00000030 E8CBFFFFFF                  call   in_subnet
57 00000035 0F95C0                      setnz  al
58 00000038 0FB6D8                      movzx  ebx, al
59 0000003B B801000000                  mov    eax, 1         ; _exit syscall
60 00000040 CD80                        int    0x80

-6 Byte aufgrund des Vorschlags von Peter Cordes, den Wert in ZF zurückzugeben.

Daniel Schepler
quelle
Ich glaube , ich ein Byte speichern könnte durch die letzte Entfernen xor edx,edxund Ersetzen cmovz eax,edxmit jz .nonzero; xor eax,eax; .nonzero:. cmovzgewinnt immer noch, wenn wir Konvention haben ebx=0.
Daniel Schepler
Können wir einfach jzüber shrdie setz oder die ret? Wir können das setnzzu tauschen setzund 1für ein Match zurückkehren, wenn das hilft. Oder sogar sagen , dass unser Rückgabewert ist ZF. Ich hätte das in meiner Antwort tun sollen. (Aber ich glaube nicht, dass wir es rechtfertigen können, dass der Aufrufer Konstanten für uns erstellt, wie ebx=0. Meine Antwort auf Tipps zum Golfen im x86 / x64-Maschinencode besagt , dass eine benutzerdefinierte Aufrufkonvention zu weit gedehnt würde.
Peter Cordes,
BTW, ich benutze cuteinige Spalten aus der NASM Listenausgabe zu entfernen , weil alle meine Anweisungen sind kurz: nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-. Außerdem habe ich in meinem _startAufrufer mov anstelle von movzx verwendet, da der Beendigungsstatus vom Low-Byte des Arg-to-Befehls stammt sys_exit(). Der Kernel ignoriert die höheren Bytes.
Peter Cordes
Ich denke das würde funktionieren. Das nimmt den Countdown bis 43 Bytes und ich dann einsetzen , setnz alnachdem call in_subnetin der Verpackung.
Daniel Schepler
Jep. Es ist leicht vorstellbar, dass der normale Anwendungsfall für diese Funktion call/ ist je, anstatt das Ergebnis zu drucken oder weiterzugeben. Wie ich in den "Tipps" ausgeführt habe, tun dies einige Aufrufkonventionen für Systemaufrufe bereits im realen Leben (normalerweise mit CF = error).
Peter Cordes
1

Java 215 211 207 202 200 199 198 190 180 Bytes

Long k,c;boolean a(String i,String s){return(b(i)^b(s))>>32-k.decode(s.split("/")[1])==0;}long b(String i){for(c=k=0l;c<4;k+=k.decode(i.split("[./]")[3+(int)-c])<<8*c++);return k;}

Ausgänge truefür wahr und falsefür falsch.

Hinweis: Dies wird longanstelle intder möglichen Rechtsverschiebung von 32 verwendet.

Probieren Sie es online!

Dank ceilingcat 1 Byte gespart

Dank Peter Cordes 10 Bytes gespart

Sack
quelle
Dies gibt keinen "eindeutigen und konsistenten Wert" für Falsey aus.
AdmBorkBork
Ich würde argumentieren, dass es eindeutig und beständig nicht null ist, aber wenn das nicht der Geist der Herausforderung ist, kann ich es ändern.
Poke
Eine 64-Bit-Ganzzahl unterstützt Linksverschiebungen um 32. Sie können auch nach rechts verschieben host ^ net, um die zu entfernenden Bits herauszuschieben, anstatt tatsächlich eine Maske zu erstellen. Aber ich denke, Java benötigt einen Vergleich, um einen Booleschen Wert aus einer Ganzzahl zu erstellen. Vielleicht a !, weil es keine Rolle spielt, welches von beiden Sie für welche Ausgabe produzieren. (Ich habe das OP um Klärung gebeten, ob sie beabsichtigen, 0 / nicht-Null auszuschließen, und sie haben zugesagt, dass sie die Konsequenzen dieser Formulierung kennen:
Peter Cordes,
1
@PeterCordes Wenn ich alles in konvertiere long, gehen mir einige Bytes verloren, aber ich kann das wieder wettmachen, indem ich das Ternäre entfernen und das XOR ausführen kann, wie Sie es vorschlagen. Ich überprüfe, was ich sonst noch Golf spielen kann, bevor ich etwas poste
Poke
1

Kohle , 36 Bytes

≔⪪S/θ≔I⊟θζ⊞θSUMθ÷↨I⪪ι.²⁵⁶X²⁻³²ζ⁼⊟θ⊟θ

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Nimmt das Subnetz als ersten Parameter und gibt -nur dann aus, wenn die Adresse innerhalb des Subnetzes liegt. Erläuterung:

≔⪪S/θ

Teilen Sie das Subnetz auf /.

≔I⊟θζ

Entfernen Sie die Maske und wandeln Sie sie in eine Ganzzahl um.

⊞θS

Übertragen Sie die Adresse auf das Array.

UMθ÷↨I⪪ι.²⁵⁶X²⁻³²ζ

Teilen Sie beide Adressen auf ., konvertieren Sie sie in Ganzzahlen, interpretieren Sie sie als Basis 256 und verwerfen Sie die maskierten Bits.

⁼⊟θ⊟θ

Vergleichen Sie die beiden Werte.

Neil
quelle
1

Japt , 26 Bytes

Ëq'/
ËÎq. Ë°¤ù8ì¯Ug1,1Ãr¶

Versuch es

-3 Bytes dank @Shaggy!

Input ist ein Array mit 2 Elementen [address, subnet]. Transpiled JS unten:

// U: implicit input array
// split elements in U on the / and
// save back to U using a map function
U = U.m(function(D, E, F) {
  return D.q("/")
});
// map the result of the previous operation
// through another function
U.m(function(D, E, F) {
  return D
    // get the address portion of the / split
    // value and split again on .
    .g().q(".")
    // map each octet through another function
    .m(function(D, E, F) {
      // convert the octet to a base 2 string
      // left padded to a length of 8
      return (D++).s(2).ù(8)
    })
    // join the base 2 octets
    .q()
    // take the left bits of the joined octets
    // determined by subnet size
    .s(0, U.g(1, 1))
})
  // at this point, the intermediate result
  // contains 2 masked values, reduce
  // using === to check for equality
  .r("===")
Dana
quelle
26 Bytes
Shaggy
Interessant - ich wusste nicht, dass Sie eine Zeichenfolge mit einer Zahl zwingen können ++.
dana
Ja, genau wie du es in JS kannst. Es nützt jedoch nichts, wenn Sie den ursprünglichen Wert später wiederverwenden müssen, ist aber gelegentlich praktisch.
Shaggy
Die Notwendigkeit für das Komma in der gMethode nervt mich; Ich kann überhaupt keinen Ausweg finden. Zumindest nicht einer, der dir ein Byte erspart.
Shaggy
0

C # (Visual C # Interactive Compiler) , 187 Byte

a=>{var b=a.Select(x=>x.Split(".").SelectMany(g=>Convert.ToString(int.Parse(g.Split("/")[0]),2).PadLeft(8)).Take(int.Parse(a[1].Split("/")[1])));return b.First().SequenceEqual(b.Last());}

Ich kann definitiv mehr Golf spielen.

Probieren Sie es online!

Verkörperung der Ignoranz
quelle
0

C # (Visual C # Interactive Compiler) , 134 Byte

a=>a.Select(x=>x.Split('.','/').Take(4).Aggregate(0L,(y,z)=>y<<8|int.Parse(z))>>32-int.Parse(a[1].Split('/')[1])).Distinct().Count()<2

Probieren Sie es online!

LINQ-Anweisung, die ein String-Array mit zwei Elementen als Eingabe in verwendet [address, subnet] Format verwendet.

Jedes gepunktete Viereck wird unter Verwendung von Bitmanipulation in 32 Bits einer Länge umgewandelt. Die Bits werden um die Subnetzgröße nach rechts verschoben und Elemente werden auf Gleichheit verglichen.

Zu dem Zeitpunkt, als diese Antwort veröffentlicht wurde, gab es ein paar C # -Antworten, aber keine, die eine reine Bit-Manipulation verwendeten.

// a: input array containing address and subnet
a=>a
  // iterate over input elements
  .Select(x=>x
    // split element on . and /
    .Split('.','/')
    // the subnet will have 5 elements,
    // we only want the parts before the /
    .Take(4)
    // use an aggregate function to convert dotted quad to 32 bits
    .Aggregate(0L,(y,z)=>y<<8|int.Parse(z))
    // shift bits of aggregate to the right
    >>
    // shift amount determined by subnet size
    32-int.Parse(a[1].Split('/')[1])
  )
  // test for equality by checking if number
  // of unique values is equal to 1
  .Distinct()
  .Count()<2
Dana
quelle