IPv4 정수 변환 기능


17

IP 주소를 정수 표현으로 변환하여 정수로 출력하는 가장 짧은 함수를 작성하십시오.

IPv4 주소를 정수 표현으로 변경하려면 다음 계산이 필요합니다.

  • IP 주소를 4 옥텟으로 나눕니다.
  • (Octet1 * 16777216) + (Octet2 * 65536) + (Octet3 * 256) + (Octet4)

샘플 입력

192.168.1.1           10.10.104.36           8.8.8.8

샘플 출력

3232235777            168454180              134744072

2
언어의 내장 기능을 금지하는 제한이 있다면 더 좋을 것 같습니다.
Nathan Osman

@George-예, 그렇습니다. 그러나 사람들은 이미 그것을 입력하기 전에 이미 해냈습니다.-솔직히 생각하지 않았습니다.
Kyle Rozendo

답변:




8

루비 (내장 / 평가 없음)-47

s=->s{s.split(".").inject(0){|a,b|a<<8|b.to_i}}

테스트:

s["192.168.1.1"]
3232235777

8

C : 79 자

main(i,a)char**a;{i=i<<8|strtol(a[1],a+1,0);*a[1]++?main(i,a):printf("%u",i);}

편집 : C ++을 제거하고 헤더없이 컴파일하지 않습니다. GCC를 사용하면 printfstrtol함수 호출에서 내장 함수를 트리거하므로 헤더를 건너 뛸 수 있습니다. 팁은 @ugoren입니다. 추가 옵션없이 그대로 컴파일됩니다 gcc.

EDIT2 : return실제로 중복됩니다 :)


main () :)의 매우 영리한 사용 .. 내 버전은 116 바이트였습니다.
akira

세그먼테이션 오류가 발생합니다.
Nathan Osman 2019

@George, 입력 내용은 무엇이며 어떻게 실행합니까?
Nim

나는 통해 내 UserScript 그것을 실행하는거야 codepad.org
나단 오스만

이것은 C ++에서 작동하지 않으므로 main을 재귀 적으로 호출 할 수 없습니다.
Scott Logan

7

골프 스크립트-16 자

{[~]2%256base}:f

독립형 프로그램으로서, 이것은 11시에 훨씬 짧습니다.

~]2%256base

매우 간단합니다. 입력 문자열 ( ~)을 평가하여 배열에 넣습니다 []. .문자열 의 s가 스택의 상단을 복제하므로 배열의 다른 모든 항만 가져옵니다 ( 2%). 이제 기본적으로 기본 256 숫자를 나타내는 배열이 있으므로 내장 함수를 사용하여 변환을 수행합니다. ( 256base).


매우 영리한. 나는 base256이 base10 또는 base16과 다르게 처리되어 48 => 0이라고 생각합니다.
gnibbler

@ gnibbler : 당신이 제안하는 것이 확실하지 않습니다. 기본 함수는 모든베이스를 동일한 방식으로 처리합니다 {:B;{\B*+}*}:base( 예 : 실제 함수는 다른 방법으로 변환을 위해 오버로드되지만). 문자열의 기본 변환은 배열과 동일합니다 (문자열은 중첩이없는 배열이지만 출력 형식이 다름).
Nabb

내가 자세히 충분히 보이지 않았다 그래서 그래 난, 문자열의 기본 변환을 생각하고 있었는데 base내 답변
gnibbler

매우 영리한. 이제 IPv6 주소를 위해 그렇게하십시오. :)
Ilmari Karonen

6

Befunge-2x11 = 22 자

너무 가까운 Befunge는 언젠가 이길 것입니다.

>&+~1+#v_.@
^*4*8*8<

설명

Befunge 의 가장 큰 특징은 대부분의 언어와 같이 선형적인 명령어 세트가 아니라는 점입니다. 제어는 모든 방향으로 흐를 수있는 단일 문자 명령어의 2 차원 격자입니다.

>      v
^      <

이 문자들은 명중 될 때 제어 방향을 변경하여 메인 루프를 만듭니다.

 &+~1+

그러면 숫자가 입력되어 스택에 푸시되고 ( &) 스택 에서 상위 2 개의 값을 가져 와서 스택에 다시 추가하고 ( +), 단일 문자를 입력하고 스택에 ASCII 값을 배치합니다 ( ~). 스택에 1을 넣고 추가합니다 ( 1+).

내가 사용한 인터프리터는 입력 종료에 대해 -1을 반환하고 일부는 0을 반환하므로 1+일부는 제거 할 수 있습니다.

      #v_.@

그러면 #다음 문자를 건너 뛰고 _스택에서 값을 팝하고 0이면 제어 권한을 보내고 그렇지 않으면 왼쪽으로 보냅니다. 값이 0 .이면 스택에서 값을 꺼내 정수로 출력 @하고 프로그램을 중지합니다. 그렇지 않으면 v제어를 리턴 루프로 보냅니다.

^*4*8*8<

이것은 단순히 스택의 최고 값에 256을 곱하고 시작으로 제어를 반환합니다.


내 무지를 용서하지만 19 자 여야합니까? 왜 2x11이라고 말했는지 이해하지만 왜 그렇게 작동합니까?
Kyle Rozendo

Befunge>v<^이 프로그램에서 실제로 주 루프 인 것을 찾는 경우 2D 언어 입니다. 이 경우 컨트롤이 실제로 맨 아래의 마지막 3 칸을 통과하지는 않지만 Befunge 프로그램을 가장 작은 경계 사각형으로 계산하는 것이 가장 쉽다는 것을 알았습니다. 제어 흐름을 시도하고 계산하려고하면 자체 수정 프로그램에 문제가 생깁니다.
Nemo157

5

루비 (40)

q=->x{x.gsub(/(\d+)\.?/){'%02x'%$1}.hex}

->

q["192.168.1.1"]
=> 3232235777

정규 표현식을 사용하는 것이 좋습니다.
Hauleth

매우 영리한! 또한 일부 문자를 저장하기 위해 to_i 16as hex를 작성할 수 있습니다 .
Paul Prestidge

감사합니다 @chron이 둘을 만들고 4 자 더 짧게 링크
jsvnm


3

골프 스크립트-21 자

{'.'/{~}%{\256*+}*}:f

좋은 고체 용액 +1. GolfScript가 비트 시프 팅 연산자를 제공하기를 원하지 않습니까? ;-) (물론, 어떤 기호를 묶어야하는지 아는 경우에 감탄합니다.)
Chris Jester-Young


3

C ++-많은 문자

#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
uint f(std::string p)
{
        std::vector<std::string> x;
        boost::split(x,p,boost::is_any_of("."));
        uint r=0;
        for (uint i = 0; i < x.size(); i++)
                r=r*256+atoi(x[i].c_str());
        return r;
}

@ 조지 에디슨 (George Edison) : 부스트를 사용하면 문자 수를 줄일 수 있습니까? :)
akira

3

PowerShell 66 61

Joey의 답변에 대한 변형 :

filter I{([ipaddress](($_-split'\.')[3..0]-join'.')).address}

PS C:\> '192.168.1.1' | I
3232235777
PS C:\> '10.10.104.36' | I
168454180
PS C:\> '8.8.8.8' | I
134744072

Argh, 나는 그것을 놓친 바보 였어야합니다 ...
Joey

3

~ 47 자 AWK

처음으로 여기에 ... 음, 어떻게 계산할 지 모르겠지만 '에코'가 없으면 AWK에서 47 자입니다. (정확하게 bogey 골프는 아니지만 구멍에 있습니다.)

echo $addr | /bin/awk -F\. '{print $1*16777216+$2*65536+$3*256+$4}'

#tbt를 위해 하루 종일 일찍, 그래서 나는 실제로 일정을 만났다! !! * 8-)

배너 일.


1
어서 오십시오! awk 스크립트에 넣은 내용의 본문 만 계산합니다. 이 답변을 참조하십시오 . 귀하의 경우에만 계산합니다 {print $1*16777216+$2*65536+$3*256+$4}. 물론 필드 구분 기호를 플래그로 지정하지 않고 프로그램으로 이동해야합니다.
Jonah

3

배쉬-46

내용의 테이블

당신은 다른 골프 버전을 찾을 수 있습니다 :

echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]                        # 46chr
set -- ${1//./ };echo $[$1<<24|$2<<16|$3<<8|$4]                       # 47chr
v=('|%d<<'{24,16,8,0});printf -vv "${v[*]}" ${1//./ };echo $[0$v]     # 65chr
mapfile -td. i<<<$1;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o  # 68chr

새로운 버전! 2018-11-15 더 골프, 46 문자

echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]

설명

  • 나는 $_더 많은 골프를 쳤다.
  • 구문 ${1//./ }은 모든 점 .을 공백으로 대체 합니다 .
  • 그래서 printf뭔가를 렌더링합니다192<<(_-=8)|168<<(_-=8)|1<<(_-=8)|1<<(_-=8)|
  • 우리는 추가됩니다 0지난 후 또는 |
  • 사전 _32 . 그래서, 왼쪽에서 오른쪽으로 구조를 읽을 $((_-=8))수 있도록 241에서 이동 , 16두 번째에, 등등.

행동 :

set -- 192.168.1.1
echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]
3232235777

재미를 위해 $_:이 후 콘텐츠 를 얻으려고 노력 하십시오.

echo $_
3232235777

;-비

set -- 192.168.1.1
echo $_ $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0] $_
192.168.1.1 3232235777 0

그래, 맞아 32 - 4 x 8 = 0

함수에서 :

ip2int() {
    echo $[_=32,`printf "%d<<(_-=8)|" ${1//./ }`0]
}
ip2int 192.168.1.1
3232235777
ip2int 255.255.255.255
4294967295
ip2int 0.0.0.0
0

또는 루프로 :-> 60

ip2int() {
    for i;do
        echo $[_=32,`printf "%d<<(_-=8)|" ${i//./ }`0]
    done
}

ip2int 192.168.1.1 10.10.104.36 8.8.8.8 1.1.1.1 255.255.255.255 0.0.0.0
3232235777
168454180
134744072
16843009
4294967295
0

배쉬 (v4.1 +) : 47

첫 번째 게시물

set -- ${1//./ };echo $[$1<<24|$2<<16|$3<<8|$4]

설명:

  • 구문 ${1//./ }은 모든 점 .을 공백으로 대체 합니다 .
  • set --위치 매개 변수 설정 ( $@=($1 $2 $3...))
  • 그래서 set -- ${1//./ }분할합니다 $1점과 세트로 $1, $2, $3$4문자열 containg 경우 3점 (공백없이).

행동 :

set -- 192.168.1.1
set -- ${1//./ };echo $[$1<<24|$2<<16|$3<<8|$4]
3232235777

또는 기능 :

ip2int() {
    set -- ${1//./ }
    echo $[$1<<24|$2<<16|$3<<8|$4]
}
ip2int 192.168.1.1
3232235777
ip2int 0.0.0.0
0

또는 루프로 :-> 61

for i;do set -- ${i//./ };echo $[$1<<24|$2<<16|$3<<8|$4];done

행동 :

ip2int() {
    for i;do
        set -- ${i//./ }
        echo $[$1<<24|$2<<16|$3<<8|$4]
    done
}

ip2int 192.168.1.1 10.10.104.36 8.8.8.8 1.1.1.1 0.0.0.0
3232235777
168454180
134744072
16843009
0

다른 버전의 골프 : 65

v=('|%d<<'{24,16,8,0});printf -vv "${v[*]}" ${1//./ };echo $[0$v]

견본:

ip2int() {
    v=('|%d<<'{24,16,8,0});printf -vv "${v[*]}" ${1//./ };echo $[0$v]
}

ip2int 255.255.255.255
4294967295
ip2int 10.10.104.36
168454180

루프 (+14)에서 : 82

ip2int() {
    for i;do
        v=('|%d<<'{24,16,8,0})
        printf -vv "${v[*]}" ${1//./ }
        echo $[0$v]
    done
}

* 또는 조금 더 추한 : 70 *

v=('|%d<<'{24,16,8});printf -vv "${v[*]}" ${1//./ };echo $[0${v%<<2*}]

경우 printf처럼 일부 문자열을주고 |192<<24 |168<<16 |1<<8|1<<24 |0<<16 |0<<8우리가 마침내 컷에 있습니다 <<2....

와 골프 mapfile, 더 이상 : 68

ip2int() {
    mapfile -td. i<<<$1;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o
}

또는 루프 포함 : 82

ip2int() {
    for a;do
      mapfile -td. i<<<$a;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o
    done
}

간단한 설명을 추가 할 수 있습니까? 나는 bash 골프에 들어 가려고 노력했지만 그 set --부분 에서 일어나는 일을 따르지 않습니다 . 감사.
요나

@Jonah : set -- foo bar웁니다 $@foo는 같은 $1$2.
F. Hauri

@Jonah 새 버전 추가
F. Hauri

설명 주셔서 감사합니다.
요나

새로운 버전! 더 골프, -1 문자 !!
F. Hauri

2

윈도우 PowerShell, 70

순진한 접근 방식 :

filter I{[int[]]$x=$_-split'\.'
$x[0]*16MB+$x[1]*64KB+$x[2]*256+$x[3]}

System.Net.IPAddress 사용시 : 76

filter I{([ipaddress]($_-replace('(.+)\.'*3+'(.+)'),'$4.$3.$2.$1')).address}

테스트:

> '192.168.1.1'|I
3232235777


2

펄 : DIY (원 라이너 용) (40)

$j=3;$i+=($_<<($j--*8))for split/\./,$x;

# $ i의 가치 사용

DIY 기능 (65) :

sub atoi{my($i,$j)=(0,3);$i+=($_<<($j--*8))for split'.',shift;$i}

당신이 사용하여 문자를 저장할 수 있도록, 문자열로 분할 할 수 있습니다 split'.'보다는split/\./
익명의 겁쟁이

어떤 기능 버전, 그래,하지만 인라인 버전으로, 당신은 필요할 것 때문에 split q{.}쉘 따옴표를 이스케이프 할 필요가 주위를 얻을 : /
켄트 프레드릭

2

하스켈-14 자

(.) a=(256*a+)

GHCi에서의 사용법 :

Prelude> let (.) a=(256*a+)
Prelude> 192. 168. 0. 1
3232235521

유일한 문제는 점의 왼쪽이나 오른쪽에 공백을 넣어야한다는 것입니다. 그렇지 않으면 숫자가 부동 소수점으로 해석됩니다.


간단한 설명을 추가 하시겠습니까?
요나

도트 인 픽스 연산자는 매우 똑똑하게 계산을 수행하도록 재정의되었습니다!
메모

이것은 매우 영리하지만 올바른 입력 형식을 사용하지 않습니다 (공백 때문에)
12Me21

2

C # – 77 자

Func<string,uint>F=s=>s.Split('.').Aggregate(0u,(c,b)=>(c<<8)+uint.Parse(b));


2

파워 쉘, 47 43 바이트

$args-split'\.'|%{$r=([long]$r-shl8)+$_};$r

테스트 스크립트 :

$f = {

$args-split'\.'|%{$r=([long]$r-shl8)+$_};$r

}

@(
    ,("192.168.1.1",3232235777)
    ,("10.10.104.36",168454180)
    ,("8.8.8.8",134744072)
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

산출:

True: 3232235777
True: 168454180
True: 134744072

1

C #-120 자

float s(string i){var o=i.Split('.').Select(n=>float.Parse(n)).ToList();return 16777216*o[0]+65536*o[1]+256*o[2]+o[3];}

내 첫 번째 코드 골프-부드럽게;)


첫 번째 '='주위의 공백을 제거 할 수 있습니다. 그러나 주요 문제는 int overflow;)입니다. IP 주소는 4 바이트를 차지합니다.
Nellius

@Nellius-아주 그렇습니다. 나는 그것을 확인조차 생각하지 않았고, 기본적으로 컴파일을 점검했다. 고마워, 이제 고칠거야.
Kyle Rozendo

1

D : 84 자

uint f(S)(S s)
{
    uint n;
    int i = 4;

    foreach(o; s.split("."))
        n += to!uint(o) << 8 * --i;

    return n;
}

나는 D를 모른다. 그래서 파이썬처럼 공백에 민감하다면 용서하십시오. 그러나 이것은 골프처럼 보이지 않습니다. 세미콜론으로 끝나는 문 사이에서 이중 줄 바꿈 또는 줄 바꿈을 제거 할 수 있습니까?
요나

1

파이썬 3.2 (69)

sum((int(j)*4**(4*i)) for i,j in enumerate(input().split('.')[::-1]))

1

PHP (내장 / 평가 없음)-54

<foreach(explode(".",$argv[1])as$b)$a=@$a<<8|$b;echo$a;

이뿐 만 아니라로 열리지 <?php않아야 <합니까?
TRiG

@ TRiG, ​​구성 파일에서 PHP 열기 구분 기호를 변경할 수 있다고 생각합니다. 이 경우에 유용합니다.
Xeoncross

@Xeoncross. 아 산뜻한. 나는 언젠가는 직장 동료들의 머리를 엉망으로 만들려고 노력할 것입니다.
TRiG September

1

펄, 14 자 :

sub _{unpack'L>',pop}

# Example usage
print _(10.10.104.36) # prints 168454180

5
14 글자를 어떻게 만드나요? 나는 21을 센다.
Peter Taylor




당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.