나는 당신의 서브넷에 있고, 당신의 코드를 골라냅니다.


17

도전

는 IPv4 감안할 때 address점선 - 쿼드 표기법과는 IPv4 subnetCIDR 표기법이 (가) 경우, 결정 address이다 subnet. 에 있으면 고유하고 일관된 값을 출력하고에 없으면 subnet별도의 고유하고 일관된 값을 출력합니다 subnet. 출력 값이 반드시 귀하의 언어에서 진실 / 거짓 일 필요는 없습니다.

CIDR 서브넷 표기법 입문서

IPv4 네트워크 주소의 길이는 32 비트이며 읽기 편하도록 8 비트의 4 개 그룹으로 나뉩니다. CIDR 서브넷 표기법은 가장 왼쪽부터 시작하여 지정된 비트 수의 마스크 입니다. 예를 들어 /24서브넷의 경우 해당 서브넷에서 주소의 가장 오른쪽 8 비트를 사용할 수 있습니다. 따라서 최대로 구분되고 255동일한 서브넷 마스크를 갖는 두 개의 주소 는 동일한 서브넷에 있습니다. 유효한 CIDR에는 모든 호스트 비트 (오른쪽)의 설정이 해제되어 있습니다 (제로).

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

다른 예에서, /32서브넷은 모든 비트가 서브넷 마스크 임을 지정합니다. 이는 기본적으로 하나의 호스트 만 허용됨을 의미합니다 /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
무지의 구현 예제에서와 같이 라인 당 하나의 라인으로 가져갈 필요는 없지만 예제에서와 같이 점으로 구분 된 서브넷과 서브넷으로 사용해야합니다. (예 : Arnauld의 JavaScript 답변 참조)
AdmBorkBork

예를 들어 슬래시로 구분해도 괜찮 10.0.0.1/10.0.0.0”/16습니까?
Nick Kennedy

1
@Poke CIDR 표기법이 IP 주소와 서브넷 크기를 설명한다는 점에 동의합니다. 에서와 같이 1.255.1.1/8유효한 CIDR 식은 서브넷 마스크가 1.255.1.1있는 네트워크 내의 호스트를 나타냅니다 . 그러나, 도전 네트워크를 요청 번호 구체적 CIDR 표기법 및 서브넷 유효한 네트워크 서브넷 번호와의 조합이 아니다. 1.0.0.0255.0.0.01.255.1.1/8
640KB 18.52에

1
이제 우리는이 도전의 IPv6 버전도 필요합니다
Ferrybig

답변:


13

파이썬 3 (62 바이트)

매우 간단합니다.

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

9
멋지지만 파이썬에는 염소를 인식하기위한 내장 기능이 있습니까?
Benjamin Urquhart가

3
물론 매스 매 티카는 빌드를-에 모든 것을위한 - 심지어 외계 행성을 위해 ! 아무것도 이길 수 없습니다 ... 그러나 당신이 볼 수 있듯이, 파이썬은 Mathematica의 염소 형태와 일치합니다
agtoever

파이썬 기반 골프 언어에 이러한 유형이없는 경우 ip_adress객체와 ip_network객체가 구성되어 any convenient method파이썬이 이길 수 있는지 궁금합니다 .
내 대명사는 monicareinstate입니다

일반적인 Python에서는 20 바이트 범위에 도달하지 않습니다. 가져 오기 및 람다 만 이미 Stax 답변보다 깁니다. 골프 언어가 "일반"언어에서 승리한다는 것은 놀라운 일이 아닙니다 ... :-(
agtoever

@ someone : 53 바이트의 x86-64 기계 코드로 Python을 이겼습니다 . :) 전통적인 골프 언어는 아니며 대부분의 코드 크기는 문자열-> 수동으로 구문 분석합니다. (host^net)>>(32-mask)10 바이트입니다. 그러나 많은 스칼라 연산은 2 또는 3 바이트 명령으로 수행 할 수 있으며 루프는 몇 바이트로 사물을 구성 할 수 있기 때문에 목록 목록과 관련이없는 작업이나 목록에 함수를 매핑하는 작업의 중간에 있습니다.
Peter Cordes

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에서 이것을 작성했지만 Arnauld는 훨씬 더 나은 대답으로 펀치에 나를 이겼습니다. 그래서 여기 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 주소를 on으로 분할하고 .각 숫자를 이진 문자열로 변환하고 각 문자열을 08 비트 길이로 왼쪽 채운 다음 문자열을 하나의 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
이 밖으로 작동, 그래서 난 그냥 너무 피곤 당신을 위해 당신 Golfed
만료 된 데이터

1
실제로 PadLeft도 잊어 버렸습니다. 온라인으로 사용해보십시오!
만료 된 데이터

많은 최적화. 당신의 rPad끈이 내장되어 있음을 알려드립니다 . 너무 오래 혼자 TIO 링크에 페이스트 빈 링크
내 대명사 monicareinstate가

2
@someone Small FYI : tinyurl.com 과 같은 URL 단축기 는 대부분의 것과 달리이 SE에 대한 의견에 허용됩니다. :)
Kevin Cruijssen '

1
188 - tinyurl.com/y6xfkbxt은 - 좋은 URL 단축 팁 @KevinCruijssen
다나

4

Linux POSIX 셸 (net-tools / iputils 사용) (34 바이트 비 종료, 47 바이트 종료)

네트워크 유틸리티 자체보다 네트워크 마스크 및 주소를 구문 분석하는 데 가장 적합한 것은 무엇입니까? :)

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

경고 : 스크립트가 인터넷 연결에 손상을 줄 수 있으므로주의해서 실행하십시오.

입력 : 스크립트는 테스트 된 IP 주소를 첫 번째 인수 및 테스트 된 서브넷으로 사용합니다. 두 번째 논쟁으로.

출력 : 스크립트의 첫 번째 인수가 두 번째 인수에 표시된 서브넷에 속하는 경우 스크립트는 정확한 값 (0)을 반환합니다. 그렇지 않으면 종료되지 않습니다.

가정 : 스크립트는 클린 환경 에서 루트 사용자로 실행해야 합니다 ( 예 : 관리자가 다른 블랙홀 경로를 설정하지 않았으며 스크립트의 이전 인스턴스가 실행 된 경우 생성 된 블랙홀 경로가 제거되었습니다). ). 스크립트는 또한 "인터넷 연결 작동"을 가정합니다 ( , 유효한 기본 경로가 존재 함).


설명:

지정된 서브넷에 대한 블랙홀 경로를 만듭니다 . 그런 다음 ping 을 사용하여 제공된 IP 주소에 대한 연결을 테스트합니다 . 주소가 서브넷에 속하지 않으면 (인터넷 연결을 올바르게 설정 했다고 가정) 은 해당 주소로 패킷을 보내려고합니다. Ping 이 계속 시도 하기 때문에이 주소가 실제로 응답하는지 여부는 중요하지 않습니다 . 반대로, 주소가 서브넷에 속하는 경우 ENETUNREACH 와 함께 실패하고 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을 반환 , 복귀 2 마지막 명령에서 테스트 한 것입니다.


3
영리한 반면, 주소가 서브넷에 없으면 명확하고 일관된 값을 출력해야하는 요구 사항을 충족하지 못합니다 ( 영구 실행은 출력으로 계산되지 않습니다 . 항목도 참조하십시오 ).
Grimmy

1
@ 그림 : 그러나 그것은 자동 으로 영원히 실행 되지 않으므로 첫 번째 링크가 아닌 두 번째 링크 만 적용됩니다. 또한 ping다른 프로그램에 stdout + stderr를 파이프로 실행하고 독자가 파이프를 닫으면 SIGPIPE로 죽을 것이라고 생각 합니다. 종료 상태는 어느 쪽이든 성공할 수 있기 때문에 가장 유스 케이스입니다 ( -c1카운트를 설정하기 위해 ping에 옵션을 추가 한 경우 ). 그러나 출력을 읽는 var=$(/a.sh)것은 실패합니다. 전체 출력을 읽은 다음 보지 않고 결정한 후에 중지 한 리더가 필요합니다.
Peter Cordes

@Grimy Fair point (논쟁의 여지가 있기 때문에 ping블랙홀 주소의 경우 1 초 미만으로 끝나기 때문에 여기서 두 개의 일관된 값이 있다고 말할 수 있습니다). 추가 13 바이트에 대한 종료 버전을 추가했습니다! :)
yoann


3

PHP , 101 92 88 바이트

@gwaugh에서 -13 바이트

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

온라인으로 사용해보십시오!


2
골프를 치는 재미가있었습니다 (Ty!) :function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
Christoph

@Christoph는 아주 좋은! 에 대한 두 번째 호출에 토큰을 사용할 수 있다고 나에게 결코 발생하지 않았습니다 strtok(). 귀하의 아래의 비슷한 답변보다 4 바이트가 짧습니다. 소품!
640KB

@Christoph 내 솔루션보다 낫기 때문에 솔루션을 별도의 답변으로 게시해야합니다.
Luis felipe De jesus Munoz

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에서 테스트되었습니다.)

프로그램은 표준 입력에서 두 줄을 취하고 종료 코드로 주소가 일치하면 1을, 그렇지 않으면 0을 반환합니다. (따라서 이것은 일치하는 값에 대한 값이 틀리거나 불일치에 대한 값의 값이 필요하지 않은 사양에 따라 달라집니다.) 대화식으로 실행하는 경우 ^D두 번째 줄을 입력 한 후 EOF ( )를 세 번 신호해야합니다 .

이는 PowerPC가 빅 엔디안이고 32 비트 부호없는 값을 32만큼 오른쪽으로 시프트 할 경우 0을 반환하는 플랫폼에 의존합니다. 다른 바이트의 넷 마스크 길이와 함께 부호없는 값을 하나씩 옥텟을 하나씩 읽습니다. ; 그런 다음 부호없는 두 32 비트 주소의 xor를 가져와 관련없는 비트를 이동시킵니다. 마지막으로 !두 개의 다른 값만 반환해야한다는 요구 사항을 충족합니다.

참고 :이 로 대체하여 두 바이트 면도 할 수있을 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);}

이 프로그램은 표준 입력에서 두 줄을 가져오고 주소가 서브넷에 있으면 종료 코드 1을 반환하고 그렇지 않으면 0을 반환합니다. (이것은 성냥에 대해서는 진솔한 값을 요구하지 않고 성냥에 대해서는 틀린 값을 요구하지 않는 사양에 의존합니다.)

핵심 표현의 분석 :

  • a^e, b^f, c^g, d^h주소의 XOR 및 바이트 단위 마스크를 계산한다.
  • (((a^e)<<8|b^f)<<8|c^g)<<8|d^h 그런 다음 Horner와 유사한 방법으로 이들을 단일 부호없는 32 비트 값으로 결합합니다.
  • ...>>32-n그런 다음 서브넷 마스크와 관련이없는 xor 차이의 비트를 이동시킵니다 ( -C보다 우선 순위가 높은 것을 명심하십시오 <<)
  • 그래도 하나의 문제가 있습니다 : n = 0이면 32 비트 ~0U<<32라고 가정하면 정의되지 않은 동작을 제공합니다 unsigned(거의 모든 현재 플랫폼에 있음). 반면에 n = 0이면 모든 주소가 일치하므로 n&&...올바른 결과를 제공합니다 (의 단락 동작을 활용 &&).
  • 마지막으로 출력이 두 값 중 하나 일 수있는 요구 사항을 충족하기 위해 !출력 0 또는 1에 적용 됩니다.

ceilingcat 및 AdmBorkBork의 주석으로 인해 -15 바이트

Peter Cordes의 설명으로 인해 -4 바이트


1
종료 코드를 사용하여 값을 리턴 하는 것은 기본 I / O 메소드 중 하나 이므로 허용됩니다.
AdmBorkBork

@ceilingcat 물론, 내가 어리석은 것을 그리워합니다.
다니엘 셰플러

@AdmBorkBork 알았어. 감사합니다. 종료 코드를 사용하도록 변경했습니다.
다니엘 셰플러

아이디어 : little-endian 또는 big-endian C 구현 (code-golf는 이식 가능한 코드가 필요하지 않음)을 타겟팅하고의 바이트에 출력 포인터를 입력하십시오 unsigned. 예를 들어 char*p=&a그때 p++,p++,p++,...또는 p--,...scanf 인수로. 형식 문자열은 "%hhu.%hhu..."그래야합니다. 따라서 추가 크기와 선언 할 수있는 수 및 추가 할 수있는 것 사이의 중요한 균형(a^b)>>(32-count)
Peter Cordes

1
@PeterCordes Yup, 올바른 변화가 효과가 있습니다. 감사합니다.
Daniel Schepler

2

Stax , 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 바이트

변경 로그:

  • jz64 비트 시프트를 사용하는 대신 시프트보다 -2>>(32-0)특수한 경우 .
  • AL 대신 ZF에서 -3을 반환하여 setnz al .

(또한보십시오 이를 기반으로 한 Daniel Schepler의 32 비트 머신 코드 답변 그러면 다른 아이디어를 사용하도록 발전했습니다.이 답변의 맨 아래에 최신 버전이 포함되어 있습니다.)


호스트에 대해 ZF = 0을 반환 아닌 경우서브넷에 , 서브넷에있는 ZF = 1을 하므로 다음과 같이 결과를 분기 할 수 있습니다.je host_matches_subnet

x86-64 System V 호출 규칙을 사용하여 호출 가능
bool not_in_subnet(int dummy_rdi, const char *input_rsi);추가 한setnz al .

입력 문자열에는 호스트와 네트워크가 모두 정확히 1 자리가 아닌 문자로 구분되어 있습니다. CIDR 너비 끝 다음의 메모리는 페이지 끝 전에 3 자리 이상의 비 바이트 바이트를 포함해야합니다. (cmdline arg와 같이 대부분의 경우 문제가되지 않습니다.) Daniel의 32 비트 버전에는이 제한이 없습니다.

동일한 dot-quad parse 루프를 3 번 ​​실행하여 두 개의 IPv4 주소를 얻고 /maskdword의 높은 바이트에서 정수를 얻습니다 . (이것이 다음에 읽기 가능한 메모리가 있어야하는 이유입니다./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

(최신 버전으로 업데이트되지 않음) 온라인으로 사용해보십시오!

A 이하 _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 integer-> 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

cmp/jcc당신이 언급 한 것 대신에 32 비트 asm 바이트 수가 어떻게 될지 궁금합니다. xor edx,edx;neg cl;cmovz eax,edx;shr eax,cl아마도 어딘가에 0 값이 걸려 있습니다. (그리고 당신은 sub cl,32지시 가 필요하지 않습니다 .)
Daniel Schepler

1
예, edi루프가 종료되면 0이되어야하는 것처럼 보이 므로 xor eax,edx;neg cl;cmovz eax,edi;shr eax,cl작동해야합니다.
Daniel Schepler

1
내가 올바르게 계산하면 cmove eax,edi3 바이트가 제거되어 워시되고 1 바이트 sub cl,32shr cl,eax저장 shr cl,rax하고 32 비트 dec edi는 64 비트를 통해 1 바이트를 저장 dec edi합니다. 내 어셈블리는 .byte 0x33(GNU binutils 구문에서) = 51을 제공 in_subnet.size합니다.
Daniel Schepler

좋은 생각이야, 고마워 (에서 인텔은 그것의 구문 shr eax,cl대, shr %cl, %eaxAT & T 구문이, 당신의 마지막 코멘트가 반전.) 그것은 업데이트 기계 코드의 답변을 기계에 의존 (및 포트의 약간의 _start발신자와 다시 설명 32 비트 모드에 대한 호출 규칙을 .. ), 그래서 나는 그것을 둘러 칠 수 없습니다. 오늘 게으른 느낌. >. <
Peter Cordes

1
방금 더블 루프를 제거하고 스택 변수에 저장하는 것에 대한 답변을 작성하려고했습니다. 쓰기 포인터를 초기화 edi하고 출력을 쓰는 등 의 추가 코드조차도 2 바이트를 절약했습니다. 그물에. (적어도 한 번은 깨달았다 push ecx;push ecx;push ecx는 것을 깨달았 으며 sub esp,12, 사전 감소 edi및 사용 std;stosb;cld여부 또는 방금 사용하여 저장했는지 여부는 세척 인 것 같습니다 dec edi;mov [edi],al.
Daniel Schepler

1

젤리 , 23 바이트

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

온라인으로 사용해보십시오!

주소와 서브넷을 슬래시로 구분하여 가져 오면 true로 1을, false로 0을 반환하는 Monadic 링크.

원본의 결함을 지적 한 @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

PHP ,75 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

온라인으로 사용해보십시오!

@Christoph 의 작은 트릭을 빌리는 -2 바이트 strtok(). 그의 대답은 여전히 ​​짧습니다!


1

x86 조립 기능, 49 43 바이트

이것은 주로 내가 만든 개정판에 대한 Peter Cordes의 요청을 충족시키기 위해 게시됩니다. 그가 한 번 / 그의 대답에 포함 시키면 사라질 수 있습니다.

이 함수는 esi주소 및 서브넷 부분이 공백 또는 개행 문자로 구분되어 입력 문자열을 가리킬 것으로 예상 되며 리턴 값은 ZF 플래그 (정의상 두 개의 가능한 값만 있음)에 있습니다.

 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 리눅스 래퍼 부분 :

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

Peter Cordes가 ZF로 값을 리턴하도록 제안하여 -6 바이트.


마지막을 제거 xor edx,edx하고로 교체 cmovz eax,edx하여 1 바이트를 절약 할 수 있다고 생각 jz .nonzero; xor eax,eax; .nonzero:합니다. cmovz우리가 전화 컨벤션을 가지고 있다면 여전히 승리합니다 ebx=0.
Daniel Schepler

수 우리 단지 jz오버 shrsetz 또는 RET에? 우리는을 교체 할 수 있습니다 setnzsetz반환 1이 도움이 경우 일치하는. 또는 우리의 반환 값 ZF 라고 말하십시오 . 나는 내 대답으로 그 일을해야했습니다. (그러나 우리는 호출자가 우리를 위해 상수를 생성하도록 요구하는 것을 정당화 할 수는 없다고 생각한다 ebx=0. x86 / x64 머신 코드에서 골프 팁에 대한 나의 대답 은 사용자 정의 호출 규칙을 너무 멀리 확장시킬 것이라고 주장한다.
Peter Cordes

BTW, cut모든 지침이 짧기 때문에 NASM 목록 출력에서 ​​일부 열을 제거 하는 데 사용 합니다 nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-. 또한 _start종료 상태가 arg의 하위 바이트에서 로 바뀌기 때문에 호출자 에서 movzx 대신 mov를 사용 했습니다 sys_exit(). 커널은 더 높은 바이트를 무시합니다.
Peter Cordes

나는 그것이 효과가 있다고 생각한다. 즉, 43 바이트의 카운트 다운을 얻어 다음 I 삽입 setnz alcall in_subnet래퍼이다.
Daniel Schepler

예. 이 기능의 일반적인 사용 사례 는 인쇄하거나 결과를 더 전달하는 것이 아니라 call/ je일 것입니다. "팁"에서 지적했듯이 일부 시스템 호출 호출 규칙은 이미 실제 상황에서이 작업을 수행합니다 (일반적으로 CF = 오류).
Peter Cordes

1

Java 21521120720220019998190180 바이트

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

출력 truetruthy 및 falsefalsy합니다.

참고 : 이것은 잠재적 인 오른쪽 시프트 32 long대신에 사용 합니다 int.

온라인으로 사용해보십시오!

ceilingcat 덕분에 1 바이트 절약

Peter Cordes 덕분에 10 바이트 절약


이것은 거짓에 대해 "명확하고 일관된 값"을 출력하지 않습니다.
AdmBorkBork

나는 그것이 명확하고 일관되게 0이 아니라고 주장하지만 그것이 도전의 정신이 아니라면 바꿀 수 있습니다.
Poke

64 비트 정수는 32만큼 왼쪽 시프트를 지원합니다. 또한 실제로 마스크를 작성하는 대신 오른쪽 시프트 host ^ net를 사용하여 제거하려는 비트를 시프트 할 수 있습니다 . 그러나 Java는 정수에서 부울을 만들기 위해 비교가 필요하다고 생각합니다. 어쩌면 a !는 어떤 출력에 대해 어떤 true 또는 false를 생성하든 문제가되지 않기 때문입니다. (나는 0 / 0이 아닌 것을 배제 할 것인지의 여부에 대해 OP에게 설명을 요청했고, 그들은 그 말의 결과를 알고 있다고 대답했다.
Peter Cordes

1
@PeterCordes 모든 것을 변환하면 long몇 바이트가 손실되지만 삼항을 제거하고 제안한대로 XOR을 수행하여 보완합니다. 게시하기 전에 다른 골프를 할 수 있는지 확인 중입니다.
Poke

1

, 36 바이트

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

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 서브넷을 첫 번째 매개 변수로 사용하고 -주소가 서브넷 내에있는 경우에만 출력 합니다. 설명:

≔⪪S/θ

에서 서브넷을 분할하십시오 /.

≔I⊟θζ

마스크를 제거하고 정수로 캐스트하십시오.

⊞θS

주소를 어레이로 푸시하십시오.

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

두 주소를 on으로 나누고 .정수로 변환하고 밑수 256으로 해석하고 마스크 된 비트를 버리십시오.

⁼⊟θ⊟θ

두 값을 비교하십시오.


1

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


흥미 로움-나는 문자열을 숫자로 강제 변환 할 수 있다는 것을 몰랐습니다 ++.
dana

예, JS에서와 마찬가지로 그래도 나중에 원래 값을 재사용해야하는 경우에는 아무 소용이 없지만 경우에 따라 편리합니다.
얽히고 설킨

g방법 에서 쉼표가 필요하다는 것은 나를 짜증나게합니다. 전혀 방법을 찾을 수 없습니다. 적어도 바이트를 절약 할 수있는 것은 아닙니다.
얽히고 설킨


0

C # (Visual C # 대화식 컴파일러) , 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

온라인으로 사용해보십시오!

2 요소 문자열 배열을 입력으로 사용하는 LINQ 문 [address, subnet] 형식 .

각 점 쿼드는 비트 조작을 사용하여 32 비트 길이로 변환됩니다. 비트는 서브넷 크기에 따라 오른쪽으로 이동하며 요소는 동일한 지 비교됩니다.

이 답변이 게시 될 당시 몇 가지 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.