私はあなたのサブネットで、あなたのコードをゴルフしています


17

チャレンジ

IPv4の所定のaddressドット付きクワッド表記で、とIPv4 subnetCIDR表記、かどうかを判断addressしていますsubnet。にある場合は明確で一貫した値を出力し、にない場合は別個の明確で一貫した値を出力subnetsubnetます。出力値は、必ずしも言語で真実/偽である必要はありません。

CIDRサブネット表記の簡単な入門書

IPv4ネットワークアドレスの長さは32ビットで、読みやすいように8ビットの4つのグループに分割されています。CIDRサブネット表記は、指定されたビット数のマスクであり、左端から始まります。たとえば、/24サブネットの場合、これはアドレスの右端の8ビットがそのサブネットで利用可能であることを意味します。したがって、最大255でで区切られ、同じサブネットマスクを持つ2つのアドレスは、同じサブネット内にあります。有効なCIDRには、すべてのホストビット(右側)が設定されていない(ゼロ)ことに注意してください。

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

別の例では、/32サブネットは、すべてのビットがサブネットマスクであることを指定します。つまり、本質的に、1つのホストのみが許可され/32ます。

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

例:

出力として「Trueサブネット内」およびFalse「サブネット内ではない」に使用:

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

規則と説明

  • 入力の解析はこの課題の興味深い点ではないため、有効なIPv4アドレスとサブネットマスクを取得することが保証されます。
  • 入力と出力は、任意の便利な方法で指定できます。
  • 結果をSTDOUTに出力するか、関数結果として返すことができます。出力でどの値を取ることができるかを提出してください。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

テストケースと同じ形式で入力する必要がありますか?
無知の具現化

1
@EmbodimentofIgnorance例のように1行に1つとる必要はありませんが、例のように点線のクワッドと点線のサブネットとする必要があります。(例:ArnauldによるJavaScriptの回答を参照)
AdmBorkBork

たとえば、スラッシュで区切っても大丈夫10.0.0.1/10.0.0.0”/16ですか?
ニックケネディ

1
@Poke CIDR表記がIPアドレスとサブネットサイズを記述するという点であなたが正しいことに同意します。のように、1.255.1.1/8有効なCIDR は、サブネットマスクを持つ1.255.1.1ネットワーク内のホストを表し1.0.0.0ます255.0.0.0。ただし、チャレンジは、CIDR表記でネットワーク番号とサブネットを明確に要求しますが、これ1.255.1.1/8は有効なネットワーク番号とサブネットの組み合わせではありません。
640KB

1
今、私たちはまた、この課題のIPv6のバージョン必要
Ferrybig

回答:


13

Python 3(62バイト)

非常に簡単です:

from ipaddress import*
lambda i,m:ip_address(i)in ip_network(m)

9
いいですが、Pythonにはヤギを認識するための組み込み機能もありますか?
ベンジャミンアーカート

3
もちろん、Mathematicaにはすべてのものが組み込まれています- 太陽系外惑星でも!何がそれを打つことはできません...しかし、あなたが見ている可能性があるので、PythonはMathematicaのヤギformaceと一致する
agtoever

ない場合、私は疑問に思うip_adressのオブジェクトとip_networkオブジェクトを構成するany convenient methodPythonベースのゴルフの言語はその種類としてこれらを持っていない限り、おそらく、Pythonの勝利をさせますか、?
私の代名詞は

通常のPythonでは20バイトの範囲では取得できません。インポートとラムダのみがすでにStax回答よりも長くなっています。ゴルフ言語が「通常の」言語から勝つことは驚くことではありません... :
agtoever

@someone:53バイトのx86-64マシンコードで Pythonを打ち負かしました。:)従来のゴルフ言語ではなく、コードサイズのほとんどはstring-> intを手動で解析します。 (host^net)>>(32-mask)わずか10バイトです。ただし、リストのリストを含まないタスク、または関数をリストにマッピングするタスクの中間点です。多くのスカラー演算は2バイトまたは3バイトの命令で実行でき、ループは数バイトで処理できるためです。
ピーターコーデス

4

C#(Visual C#コンパイラ)、250 + 31 = 281バイト

(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);};

バイトカウントに含まれるもの using System;using System.Linq;

オンラインでお試しください!

チャレンジが投稿されるとすぐにこれをJSで書きましたが、アーナウルドはより良い答えで私を打ち負かしましたので、代わりにC#にあります。

ゴルフのための間違いなく多くの部屋。

説明:

この関数は、次のサブ関数で構成され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;
    }
);

このサブ関数は、IPアドレスを.で分割し、各数値をバイナリ文字列に変換し、各文字列を08ビット長になるように左詰めして、文字列を1つの32ビットバイナリ文字列に連結します。

これはa=h(a);、指定されたIPアドレスですぐにインプレースで実行されます。
次に、サブネットマスクをIPアドレスとマスク番号に分割します。c=b.Split('/');

IPアドレスコンポーネントもサブ関数を介して渡されます。b=h(c[0]);マスク番号は整数に解析されます。var d=int.Parse(c[1]);

最後にd、両方のバイナリ文字列の最初のビット(dマスク番号)を取得して比較します。return a.Substring(0,d)==b.Substring(0,d);


1
これを解決するのに疲れすぎたので、私はあなたのためにゴルフをしました
期限切れのデータ


最適化がたくさん。あなたrPadが文字列に組み込まれていることをお知らせします。単独では長すぎるTIOリンクへのpastebinリンク
私の代名詞はmonicareinstate

2
@someone Small FYI:ほとんどの場合とは異なり、tinyurl.comのようなURL短縮はこのSEのコメントで許可されています。:)
ケビンクルーッセン

1
188 - tinyurl.com/y6xfkbxtは -素敵なURL短縮のヒントは@KevinCruijssen
ダナ

4

Linux POSIXシェル(net-tools / iputilsを使用)(34バイトの非終了、47バイトの終了)

ネットワークマスクとアドレスの解析に最も適しているのは、ネットワークユーティリティ自体よりも何ですか?:)

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

警告:スクリプトはインターネット接続に損害を与える可能性があるため、注意して実行してください。

入力:スクリプトは、テストされたIPアドレスを最初の引数として受け取り、テストされたサブネットを受け取ります。2番目の引数として。

出力:スクリプトの最初の引数が2番目の引数で示されたサブネットに属する場合、スクリプトは真理値(0)を返します。それ以外の場合は、終了しません。

前提条件:スクリプトはクリーンユーザー環境でrootユーザーとして実行する必要があります(つまり、管理者によって他のブラックホールルートが設定されておらず、スクリプトの以前のインスタンスが実行された場合、作成されたブラックホールルートは削除されました) )。また、このスクリプトは「有効なインターネット接続」を想定しています(つまり、有効なデフォルトルートが存在します)。


説明:

指定されたサブネットへのブラックホールルートを作成します。次に、pingを使用して、提供されたIPアドレスへの接続をテストします。アドレスがサブネットに属していない場合(インターネット接続が適切に設定されていると想定しているため)、pingはそのアドレスにパケットを送信しようとします。このアドレスが実際に応答するかどうかは問題ではないことに注意してください。pingは永遠に試行を続けるためです。逆に、アドレスがサブネットに属している場合、pingENETUNREACHで失敗し、2を返します。コマンドを無効にしたため、スクリプトは成功します。


5.5.5.5が8.8.8.0/24に属するかどうかをテストします

$ 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...]

sudo ip route del 8.8.8.0/24コマンドの実行後にクリーンアップします)。

5.5.5.5が5.5.5.0/24に属するかどうかをテストします。

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

sudo ip route del 5.5.5.0/24コマンドの実行後にクリーンアップします)。

8.8.8.8が5.5.5.0/24に属するかどうかをテストします。

$ 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...]

sudo ip route del 5.5.5.0/24コマンドの実行後にクリーンアップします)。


終了しないスクリプトを許可しない場合の47バイトバージョン

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

@Grimyのコメントによると、これは常に終了し、アドレスがサブネット内にある場合は0(真)を返し、そうでない場合は1(偽)を返すバージョンです。私たちは、作るpingがで終了し-c1たアドレスが応答した場合、1に送信されたパケットの数を制限フラグpingが 0を返し、ない場合は、アドレスがしますブラックホールサブネットに属している場合にのみ、pingは1を返しますpingを実行、復帰2したがって、これは最後のコマンドでテストするものです。


3
賢い間、これはアドレスがサブネットにない場合、明確で一貫した値を出力するための要件を満たしていません(永久に実行は出力としてカウントされませんこれも参照)。
グリミー

1
@Grimy:しかし、静かに永久に実行されるわけではないため、最初のリンクではなく、2番目のリンクのみが適用されます。またping、stdout + stderrが別のプログラムにパイプされて実行されていて、リーダーがパイプを閉じた場合、SIGPIPEで死ぬと思います。終了ステータスはどちらの方法でも成功する可能性があるため、これが最も可能性の高いユースケースです(-c1カウントを設定するためにpingにオプションを追加した場合)var=$(/a.sh)。出力全体を読んでから見るのではなく、決定後に停止するリーダーが必要です。
ピーターコーデス

@Grimy Fair point(議論のために、ここでは2つの一貫した値pingがあると言えます。ブラックホールアドレスの場合、1秒未満で終了するからです)。余分な13バイトの終了バージョンを追加しました!:)
yoann


3

PHP101 92 88バイト

@gwaughから-13バイト

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

オンラインでお試しください!


2
ゴルフを楽しんだ(タイ!):function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
クリストフ

@Christophとても素敵です!の2回目の呼び出しにトークンを使用できるとは決して思いませんでしたstrtok()。以下は、非常によく似た答えよりも4バイト短いです。小道具!
640KB

@Christoph私のソリューションよりも優れているため、ソリューションを個別の回答として投稿する必要があります。
ルイス・フェリペ・デ・イエス・ムニョス

3

PowerPC / PPC64 C、 116 114バイト

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

(powerpc64-linux-gnu-gcc -staticおよびqemu-userを使用して、x86_64 Ubuntu 18.04でテスト済み。)

プログラムは標準入力の2行を使用し、アドレスが一致する場合は終了コードとして1を返し、一致しない場合は0を返します。(つまり、これは仕様に一致するために真実の値と不一致のために偽の値を必要としないことに依存します。)対話的に実行している場合^D、2行目を入力した後にEOF()を3回シグナルする必要があることに注意してください。

これは、PowerPCがビッグエンディアンであること、および32ビットの符号なし値を32だけ右シフトするためにプラットフォームが0を返すことに依存しています。オクテットを符号なしの値に1つずつ読み取り、ネットマスクの長さを別のバイトで; 次に、2つの符号なし32ビットアドレスのxorを取得し、無関係なビットをシフトアウトします。最後に、!2つの異なる値のみを返すという要件を満たすために適用されます。

注:と置き換えてコンパイルを必要とすることにより、2バイトを削ることできる場合があります。しかし、それは私が気にするよりも危険にさらされています。u+3p-O0

このソリューションのインスピレーションを与えてくれたPeter Cordesに感謝します。


よりポータブルなC、 186 171 167バイト

ここでは、167バイトを実行する、よりポータブルなバージョンを保持します。

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

このプログラムは、標準入力で2行を取り、アドレスがサブネット内にある場合は終了コード1を返し、そうでない場合は0を返します。(したがって、これは、一致には真理値、非一致には偽値を必要としない仕様に依存しています。)

コア式の内訳:

  • a^eb^fc^gd^hアドレスおよびマスクバイト単位のXORを計算します。
  • (((a^e)<<8|b^f)<<8|c^g)<<8|d^h 次に、それらをホーナーのような方法で単一の符号なし32ビット値に結合します。
  • ...>>32-n次に、サブネットマスクに関係のないxor差​​分のビットをシフトします(-Cよりも優先順位が高いことに注意してください<<)。
  • ただし、1つの落とし穴があります。n= 0の場合、32ビット(これは事実上すべての現在のプラットフォーム上にある)であると~0U<<32仮定すると、未定義の動作が発生しunsignedます。一方、n = 0の場合、すべてのアドレスが一致n&&...するため、正しい結果が得られます(の短絡動作を利用します&&)。
  • 最後に、出力が2つの値のうちの1つにしかならないという要件を満たすために、!出力0または1に適用します。

ceilingcatおよびAdmBorkBorkによるコメントのため、-15バイト

ピーター・コードによるコメントのため、-4バイト


1
終了コードを使用して値を返すことは、デフォルトのI / Oメソッドの1つであり、許可されています。
AdmBorkBork

@ceilingcatもちろん、それを見逃すなんて馬鹿げている。
ダニエルシェプラー

@AdmBorkBork OK、ありがとう、終了コードを使用するように変更しました。
ダニエルシェプラー

アイデア:リトルエンディアンまたはビッグエンディアンのC実装(code-golfは移植可能なコードを必要としません)をターゲットにし、のバイトに出力型ポインターを入力しますunsigned。例えば、char*p=&athen p++,p++,p++,...またはp--,...scanf引数として。"%hhu.%hhu..."ただし、フォーマット文字列は必要であるため、余分なサイズと宣言する変数の数を減らすことと、できることとの間の重要なトレードオフです(a^b)>>(32-count)
Peter Cordes

1
@PeterCordesうん、右シフトが機能します、ありがとう。
ダニエルシェプラー

2

スタックス、22 バイト

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

実行してデバッグする

これは、標準入力でスペースで区切られた入力パラメーターを取ります。

開梱されていない、コメントされていない、これはこのように見えます。

'/:/~       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?

これを実行する


2

x86-64マシンコード関数、53 48バイト

変更ログ:

  • 特殊なケースjzを処理するために64ビットシフトを使用する代わりに、シフトを介して-2 >>(32-0)
  • -3はALの代わりにZFで戻り、の3バイトを節約しますsetnz al

(これに基づいたDaniel Scheplerの32ビットマシンコードの回答も参照してください。これはその後、他のアイデアを使用するように進化しました。この回答の最後に最新バージョンを含めます。)


サブネットにないホストに対してはZF = 0を返し、サブネットにある場合はZF = 1を返すので、結果で分岐できますje host_matches_subnet


bool not_in_subnet(int dummy_rdi, const char *input_rsi);を追加するかのように、x86-64 System V呼び出し規約で呼び出し可能setnz al

入力文字列には、ホストとネットワークの両方が含まれ、1桁の非数字文字で区切られています。CIDR幅の終わりに続くメモリには、ページの終わりまでに少なくとも3桁の非数字バイトが含まれている必要があります。(ほとんどの場合、cmdline argのように問題になることはありません。)Danielの32ビットバージョンにはこの制限はありません。

同じドット付きクワッド解析ループを3回実行して、2つのIPv4アドレスを取得し/mask、dwordの上位バイトの整数として取得します。(これが、の後に読み取り可能なメモリが必要な理由/maskですが、ASCII数字があるかどうかは関係ありません。)

私たちは、やる(host ^ subnet) >> (32-mask)ホストビットシフトアウトしたサブネットとホスト間の唯一の違いを残し、(不整合のために許可されたものを)。/032シフトする必要がある特殊なケースを解決するために、count = 0のシフトを飛び越えます。(neg cl私たちは上分岐できるセットZF、私たちはシフトしていない場合は、戻り値として休暇。)なお32-mask mod 32 = -mask、およびx86スカラーシフトはによって彼らの回数を隠します& 31& 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

(最新バージョンでは更新されません) オンラインで試してください!

_start呼び出してargv[1]終了ステータスを返すを含む。

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

スペースの代わりに改行を含むコマンドライン引数を渡すと正常に動作します。ただし、代わりにである必要があります。


x86 32ビットマシンコード関数、38バイト

9整数-> uint8_tを解析し、スタックに「プッシュ」します。そこで、それらをdwordとしてポップオフするか、CLに残っている最後のものを使用します。文字列の終わりを超えて読み取らないようにします。

また、dec32ビットモードでは1バイトのみです。

    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

テスト発信者

   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

32ビットのasmバイトカウントはcmp/jcc、あなたが言及したものの代わりに何かをした場合にどうなるのか、xor edx,edx;neg cl;cmovz eax,edx;shr eax,clまたは既に0の値がどこかにぶら下がっている場合はどうでしょうか。(そして、あなたはsub cl,32指示を必要としません。)
ダニエル・シェプラー

1
うん、ediループが終了すると0になるはずなので、動作するxor eax,edx;neg cl;cmovz eax,edi;shr eax,clはずです。
ダニエルシェプラー

1
私は正しいことをカウントした場合、cmove eax,edi洗浄の上にある3つのバイトを有する除去sub cl,32次いで、shr cl,eax上の1つのバイトを節約shr cl,raxし、32ビットdec edi、64ビット上の1つのバイトを節約しますdec edi。その後、私のアセンブリは.byte 0x33(GNU binutils構文で)= 51を与えますin_subnet.size
ダニエルシェプラー

いいアイデア、ありがとう。(Intel構文ではshr eax,cl、vs shr %cl, %eax. AT&T構文では、最後のコメントはそれを逆転させました。)マシンコードの回答を更新するのは少し面倒です(そして、_start呼び出し元を移植し、32ビットモードの呼び出し規約を再記述します。) 。)ので、私はそれを回避することはできません。今日は怠zyな感じ。>。<
ピーター・コード

1
ダブルループを取り除き、代わりにスタック変数に保存するという答えにあなたが書いたコメントを実装しようとしました-書き込みポインタを初期化するedi、出力を書き込むなどの余分なコードでも、2バイトを節約しましたネットで。(私が実現したら、少なくとも、push ecx;push ecx;push ecxより短かったsub esp,12;そして私がプリデクリメントするかどうかを洗浄ように見えたedi、使用std;stosb;cldまたは私はちょうど使用して保存されたかどうかdec edi;mov [edi],al
ダニエルSchepler

1

ゼリー、23バイト

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

オンラインでお試しください!

スラッシュで区切られたアドレスとサブネットを受け取り、trueの場合は1、falseの場合は0を返すモナドリンク。

オリジナルの欠陥を指摘してくれた@gwaughに感謝します-バイナリリストの長さが32であることを保証できませんでした。



1

05AB1E、21 バイト

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

アドレスの前にサブネットを取得します。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

'/¡              '# 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)

1

R 120バイト

関数-最初の用語に「.32」を貼り付けました

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

そしてただの楽しみのために:

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

56バイトです


1

PHP75 73、71バイト

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

@Luis felipe De jesus Munozの回答、コマンドライン引数からの入力を取るスタンドアロンとしてのフォーク。'1'Truthyの出力、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

オンラインでお試しください!

-2バイトは、@ Christophの小さなトリックを借りていstrtok()ます。彼の答えはまだ短いです!


1

x86アセンブリ関数、 49 43バイト

これは主に、私が作成した改訂版に対するPeter Cordesの要求を満たすために投稿されています。それはおそらく一度/彼が彼の答えにそれを組み込むならば、消えることができます。

この関数はesi、スペースまたは改行文字で区切られたアドレス部分とサブネット部分を持つ入力文字列を指すことを期待し、戻り値はZFフラグ(定義により2つの可能な値のみ)にあります。

 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

そして、x86 Linuxラッパーパーツ:

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

ZFで値を返すためのPeter Cordesからの提案による-6バイト。


私は最後を除去することにより、1つのバイトを救うことができると思いますxor edx,edxし、交換するcmovz eax,edxjz .nonzero; xor eax,eax; .nonzero:cmovz呼び出し規約があればまだ勝ちですebx=0
ダニエルシェプラー

setzやretをjz越えていくことができますshrか?setnzto setzを交換して1、一致する場合は、それが役立つ場合に戻ることができます。または、戻り値 ZF であると言うこともできます。私は私の答えでそれをすべきだった。(しかし、私のような、私たちは私たちのために定数を作成するには、発信者を必要とする正当化することができるとは思わないebx=0で私の答え。のx86 / x64のマシンコードにゴルフのヒントは、それはあまりにも遠く呼び出し規約カスタムを伸ばすことになると主張している。
ピーター・コルド

ところで、cutすべての指示が短いため、NASMリスト出力からいくつかの列を削除します nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-。また、_start呼び出し元でmovzxの代わりにmovを使用しました。これは、終了ステータスがargの下位バイトからになっているためsys_exit()です。カーネルは上位バイトを無視します。
ピーターコーデス

それはうまくいくと思います。これはカウントを43バイトに減らし、ラッパーにsetnz alafter を挿入call in_subnetします。
ダニエルシェプラー

うん。この関数の通常の使用例は、印刷したり、結果をさらに渡すのではなく、call/ jeになると簡単に想像できます。「ヒント」で指摘したように、一部のシステムコール呼び出し規約は、実際にこれをすでに実行しています(通常はCF = errorを使用)。
ピーターコーデス

1

Java 215 211 207 202200199198190180バイト

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

true真実と虚偽の出力false

注:これは、32の潜在的な右シフトのlong代わりに使用しintます。

オンラインでお試しください!

ceilingcatのおかげで1バイト節約

Peter Cordesのおかげで10バイト節約


これはfalseyに対して「明確で一貫した値」を出力しません。
AdmBorkBork

はっきりと一貫してゼロではないと主張しますが、それがチャレンジの精神でない場合は、変更できます。
ポケ

64ビット整数は、32による左シフトをサポートします。また、実際にマスクを作成する代わりに、シフトhost ^ netして削除するビットをシフトアウトできます。しかし、整数からブール値を作成するには、Javaでの比較が必要だと思います。たぶん、!それはあなたがどの出力のために真または偽を生成するかは重要ではないからです。(私はOPに0 /非ゼロを除外するつもりであるかどうかを明確にするように依頼し、その文言の結果を知っていると答えました:
Peter Cordes

1
@PeterCordesすべてをに変換すると、longいくつかのバイトが失われますが、3項を削除し、提案されているようにXORを実行することでそれを補います。私は投稿する前に他に何のI缶ゴルフをチェックしています
ポケ

1

、36バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。サブネットを最初のパラメーターとして使用し-、アドレスがサブネット内にある場合にのみ出力します。説明:

≔⪪S/θ

でサブネットを分割します/

≔I⊟θζ

マスクを削除して整数にキャストします。

⊞θS

アドレスを配列にプッシュします。

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

両方のアドレスを.で分割し、それらを整数に変換し、ベース256として解釈し、マスクされたビットを破棄します。

⁼⊟θ⊟θ

2つの値を比較します。


1

Japt、26バイト

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

それを試してみてください

@Shaggyのおかげで-3バイト!

入力は2要素の配列[address, subnet]です。以下のJSをコンパイルします。

// 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("===")


興味深い-私はあなたが文字列を数字に強制することができることを理解していませんでした++
ダナ

うん、JSでできるように。ただし、後で元の値を再利用する必要がある場合は役に立ちませんが、場合によっては便利です。
シャギー

gメソッドにコンマが必要なのは面倒です。それを回避する方法がまったくわかりません。少なくとも1バイトは節約できません。
シャギー


0

C#(Visual C#Interactive Compiler)、134バイト

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

オンラインでお試しください!

[address, subnet]形式の入力として2要素の文字列配列を受け取るLINQステートメント。

各ドット付きクワッドは、ビット操作を使用して32ビットのlongに変換されます。ビットはサブネットサイズによって右にシフトされ、要素が等しいかどうか比較されます。

この回答が投稿された時点でいくつかのC#回答がありましたが、純粋なビット操作を使用した回答はありませんでした。

// 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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.