IPv4-Integer-Konvertierungsfunktion

17

Schreiben Sie die kürzeste Funktion, um eine IP-Adresse in ihre Ganzzahldarstellung umzuwandeln und als Ganzzahl auszugeben.

Um eine IPv4-Adresse in eine Ganzzahldarstellung zu ändern, ist die folgende Berechnung erforderlich:

  • Teilen Sie die IP-Adresse in vier Oktette auf.
  • (Octet1 * 16777216) + (Octet2 * 65536) + (Octet3 * 256) + (Octet4)

Sample Input

192.168.1.1           10.10.104.36           8.8.8.8

Beispielausgabe

3232235777            168454180              134744072
Kyle Rozendo
quelle
2
Ich denke, das wäre besser, wenn es eine Einschränkung gäbe, die die eingebauten Funktionen einer Sprache verbietet.
Nathan Osman
@George - Ja, das wäre es gewesen, aber die Leute hatten es bereits getan, bevor ich das einbauen konnte - ich habe ehrlich gesagt nicht darüber nachgedacht.
Kyle Rozendo

Antworten:

11

PHP - 21 Zeichen

<?=ip2long($argv[1]);
ircmaxell
quelle
8

MySQL - 20 Zeichen

SELECT INET_ATON(s);
ircmaxell
quelle
8

Ruby (keine eingebauten / bewerteten) - 47

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

Prüfung:

s["192.168.1.1"]
3232235777
Arnaud Le Blanc
quelle
8

C: 79 Zeichen

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

BEARBEITEN: entfernte C ++, würde nicht ohne Überschriften kompilieren; Mit GCC lösen die Funktionsaufrufe printfund strtoleingebaute Funktionen aus, daher können Header übersprungen werden. Danke an @ugoren für die Tipps. Dies wird so kompiliert wie es ist ohne zusätzliche Optionen zu gcc.

EDIT2: returnist eigentlich überflüssig :)

Nim
quelle
sehr kluger Gebrauch von main () :) .. meine Version war 116bytes.
Akira
Ich habe einen Segmentierungsfehler.
Nathan Osman
@ George, was ist dein Input und wie machst du es?
Nim
Ich starte es mit meinem UserScript über codepad.org
Nathan Osman
Dies funktioniert in C ++ nicht, Sie können main nicht rekursiv aufrufen.
Scott Logan
7

Golfscript - 16 Zeichen

{[~]2%256base}:f

Als eigenständiges Programm ist dies mit 11 noch kürzer.

~]2%256base

Sehr einfach. Wertet die Eingabezeichenfolge ( ~) aus und fügt sie in ein Array ein []. Da das .s in der Zeichenfolge das obere Ende des Stapels dupliziert, nehmen wir nur jeden anderen Ausdruck in das Array ( 2%). Wir haben jetzt ein Array, das im Grunde genommen eine Basis-256-Zahl darstellt. Daher verwenden wir eine eingebaute Funktion, um die Konvertierung durchzuführen. ( 256base).

Nabb
quelle
sehr schlau. Ich denke, base256 wird anders behandelt, um base10 oder base16 zu sagen, wo dann 48 => 0?
Knabberzeug
@gnibbler: Ich bin mir nicht sicher, was Sie vorschlagen - die Basisfunktion behandelt alle Basen auf die gleiche Weise, z. B. {:B;{\B*+}*}:base(obwohl die eigentliche Funktion für Konvertierungen in die andere Richtung überladen ist). Interessant ist, dass die Basiskonvertierung für Strings mit Arrays identisch ist (da Strings nur Arrays ohne Verschachtelung sind, aber ein anderes Ausgabeformat haben).
Nabb
Ja, ich dachte an base
grundlegende
Sehr schlau. Tun Sie dies jetzt für eine IPv6-Adresse. :)
Ilmari Karonen
6

Befunge - 2x11 = 22 Zeichen

Befunge gewinnt eines Tages.

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

Erläuterung

Das größte Unterscheidungsmerkmal von Befunge ist, dass es sich nicht wie bei den meisten Sprachen um einen linearen Befehlssatz handelt. Es ist ein 2D-Raster von Einzelzeichenanweisungen, bei denen die Steuerung in jede Richtung fließen kann.

>      v
^      <

Diese Charaktere ändern die Richtung der Steuerung, wenn sie getroffen werden, dies macht die Hauptschleife.

 &+~1+

Dieser gibt eine Zahl ein und legt sie auf den Stapel ( &), entfernt die beiden obersten Werte vom Stapel, fügt sie hinzu +und legt sie zurück auf den Stapel ( ), gibt ein einzelnes Zeichen ein und legt dann seinen ASCII-Wert auf den Stapel ( ~) schiebt 1 auf den Stapel und fügt sie hinzu ( 1+).

Der Interpreter, den ich verwendet habe, gibt -1 für das Ende der Eingabe zurück, einige geben stattdessen 0 zurück, damit der 1+Teil für sie entfernt werden kann.

      #v_.@

Das #bewirkt, dass das nächste Zeichen übersprungen wird, dann wird _ein Wert aus dem Stapel entfernt, und wenn er Null ist, wird die Steuerung nach rechts gesendet, andernfalls wird der Wert nach links gesendet. Wenn der Wert Null war, wird .ein Wert vom Stapel entfernt, als Ganzzahl ausgegeben und @das Programm gestoppt. Ansonsten wird die vSteuerung an die Rückführschleife gesendet.

^*4*8*8<

Dies multipliziert einfach den obersten Wert des Stapels mit 256 und gibt die Kontrolle an den Start zurück.

Nemo157
quelle
Entschuldigen Sie meine Unwissenheit, aber sollten das 19 Zeichen sein? Ich verstehe, warum du 2x11 sagst, aber warum funktioniert das so?
Kyle Rozendo
Befunge ist eine 2d Sprache, wenn man das sucht >v<^ist das eigentlich die Hauptschleife in diesem Programm. In diesem Fall passiert die Steuerung vermutlich nicht die letzten drei Leerzeichen unten, aber ich finde es am einfachsten, Befunge-Programme als kleinstes Begrenzungsrechteck zu zählen. und wenn Sie versuchen, den Kontrollfluss zu zählen, bekommen Sie Probleme mit selbstmodifizierenden Programmen.
Nemo157,
5

Rubin (40)

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

->

q["192.168.1.1"]
=> 3232235777
jsvnm
quelle
Gute Idee, regexp zu verwenden.
Hauleth
Sehr schlau! Sie können auch schreiben to_i 16als hexeinige Zeichen zu speichern.
Paul Prestidge
danke @chron, dass sowohl dies als auch Link 4 Zeichen kürzer gemacht
jsvnm
4

Rubin - 46 Zeichen

require"ipaddr"
def f s;IPAddr.new(s).to_i;end
Knabberzeug
quelle
Ich denke, das ist Betrug. ;-)
Chris Jester-Young
3

Golfscript - 21 Zeichen

{'.'/{~}%{\256*+}*}:f
Knabberzeug
quelle
+1 Gute feste Lösung. Wünschen Sie nicht, dass GolfScript Bit-Shifting-Operatoren bereitstellt? ;-) (Allerdings, verdammt, wenn ich weiß, an welche Symbole sie gebunden werden sollen.)
Chris Jester-Young
3

Python 56 45

c=lambda x:eval('((('+x.replace('.','<<8)+'))
Alexandru
quelle
3

C ++ - viele Zeichen

#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;
}
grokus
quelle
@ George Edison: Die Verwendung von Boost hilft dabei, die Anzahl der Zeichen zu verringern. :)
Akira
3

Power Shell 66 61

Variation über Joeys Antwort:

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
Ty Auvil
quelle
Argh, ich muss dumm gewesen sein, das verpasst zu haben ...
Joey
3

AWK in ~ 47 Zeichen

Der Erstbesucher hier ... Ähm, ich weiß nicht, wie ich das zählen soll, aber ohne das Echo sind es 47 Zeichen in AWK. (Nicht gerade Bogey Golf, aber es ist im Loch.)

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

Ganztägig früh auch für #tbt, also habe ich tatsächlich einen Zeitplan getroffen !!! * 8-)

Bannertag.

Blair Wyman
quelle
1
Herzlich willkommen! Sie würden nur den Text zählen, den Sie in ein awk-Skript geschrieben haben. Siehe diese Antwort . In Ihrem Fall würden Sie nur zählen {print $1*16777216+$2*65536+$3*256+$4}. Natürlich müssten Sie das Feldtrennzeichen in das Programm verschieben, anstatt es als Flag anzugeben.
Jona,
3

Bash - 46

Inhaltsverzeichnis

Sie finden 4 verschiedene Golfvarianten:

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

Neue Version! 2018-11-15 Golfspieler, 46 char

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

Erläuterung

  • ich benutzte $_ mehr Golf gespielt.
  • Die Syntax ${1//./ }ersetzt alle Punkte .durch Leerzeichen .
  • so printf wird etwas rendern192<<(_-=8)|168<<(_-=8)|1<<(_-=8)|1<<(_-=8)|
  • dann werden wir ein 0nach dem letzten ODER hinzufügen | und
  • voreingestellt _auf 32 . liest das Konstrukt von links nach rechts, $((_-=8))machen Sie also 24bei der ersten Schicht , 16bei der zweiten und so weiter.

in Aktion:

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

Zum Spaß: versuche $_Inhalte zu bekommen , danach:

echo $_
3232235777

-b

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

Ok, das stimmt 32 - 4 x 8 = 0

In einer Funktion:

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

oder in eine Schleife: -> 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

Bash (v4.1 +): 47

Erster Beitrag

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

Erläuterung:

  • Die Syntax ${1//./ }ersetzt alle Punkte .durch Leerzeichen .
  • set --eingestellt Positionsparameter ( $@=($1 $2 $3...))
  • So set -- ${1//./ }wird geteilt $1durch Punkte und Satz $1, $2, $3und $4wenn der String containg 3Punkte (ohne Leerzeichen).

in Aktion:

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

oder in einer Funktion:

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

oder in eine Schleife: -> 61

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

in Aktion:

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

Eine andere Version anders golfen: 65

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

Stichprobe:

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

In einer Schleife (+14): 82

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

* oder etwas hässlicher: 70 *

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

Wo printfgibst |192<<24 |168<<16 |1<<8|1<<24 |0<<16 |0<<8du eine Schnur wie wir müssen endlich schneiden <<2....

gespielt mit mapfile, länger: 68

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

oder mit Schleife: 82

ip2int() {
    for a;do
      mapfile -td. i<<<$a;for((a=o=0;a<4;o+=i[a]<<(3-a++)*8)){ :;};echo $o
    done
}
F. Hauri
quelle
könntest du eine kurze Erklärung hinzufügen? Ich habe versucht, mich auf das Bash-Golfen einzulassen, und ich verfolge nicht, was mit dem set --Teil passiert . Vielen Dank.
Jonah
@Jonah: set -- foo barwird $@mit foo as $1und bar as gefüllt $2.
F. Hauri
@Jonah Neue Version hinzugefügt
F. Hauri
Danke für die Erklärung.
Jonah,
Neue Version! mehr Golf, -1 char !!
F. Hauri
2

Windows PowerShell, 70

Naiver Ansatz:

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

Mit der Verwendung von System.Net.IPAddress: 76

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

Prüfung:

> '192.168.1.1'|I
3232235777
Joey
quelle
2

Befunge-93 - 36 Zeichen

&"~"2+::8****&884**:**&884***&++++.@
MiffTheFox
quelle
2

Perl: DIY (für Oneliner.) (40)

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

# Verwenden Sie den Wert in $ i

DIY-Funktion (65):

sub atoi{my($i,$j)=(0,3);$i+=($_<<($j--*8))for split'.',shift;$i}
Kent Fredric
quelle
Sie können durch eine Schnur aufgespalten, so dass Sie durch die Verwendung eines Zeichens speichern und split'.'nichtsplit/\./
anonymen Feigling
Mit der Funktionsversion, ja, aber der Inline-Version, nein, weil Sie die Notwendigkeit umgehen müssten split q{.}, Shell-Anführungszeichen zu umgehen: /
Kent Fredric
2

Haskell - 14 Zeichen

(.) a=(256*a+)

Verwendung in GHCi:

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

Das einzige Problem ist, dass Sie links oder rechts vom Punkt Leerzeichen einfügen müssen, da sonst die Zahlen als Gleitkomma interpretiert werden.

quasimodo
quelle
etwas dagegen, eine kurze Erklärung hinzuzufügen?
Jonah,
Der Punkt-Infix-Operator wird für die Berechnung neu definiert, was in der Tat sehr klug ist!
Memo
Das ist sehr clever, aber es verwendet nicht das richtige Eingabeformat (wegen der Leerzeichen)
12Me21
2

77 Zeichen

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

JavaScript (45 Zeichen)

Benötigt Unterstützung für die .reduce()Array - Methode in ES5 und eingeführt Pfeil Funktionen .

f=(x)=>x.split('.').reduce((p,c)=>p<<8|c)>>>0
PleaseStand
quelle
Huh ... ich wusste nicht, dass >>> so funktioniert (Umwandlung in vorzeichenlose 32-Bit-Ganzzahlen)
12Me21
2

Powershell, 47 43 Bytes

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

Testskript:

$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"
}

Ausgabe:

True: 3232235777
True: 168454180
True: 134744072
mazzy
quelle
1

120 Zeichen

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

Mein erster Code Golf - sei sanft;)

Kyle Rozendo
quelle
Sie können die Leerzeichen um Ihr erstes "=" entfernen. Ihr Hauptproblem ist jedoch int overflow;). Denken Sie daran, dass eine IP-Adresse 4 volle Bytes beansprucht.
Nellius
@ Nellius - ganz richtig. Ich habe nicht einmal daran gedacht, das zu überprüfen, im Grunde genommen beim Kompilieren. Danke, werde das jetzt beheben.
Kyle Rozendo
1

D: 84 Zeichen

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

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

    return n;
}
Jonathan M Davis
quelle
Ich weiß es nicht. Verzeih mir, wenn es Whitespace-empfindlich ist wie Python, aber das sieht nicht gut aus. können Sie die doppelten Zeilenumbrüche oder die Zeilenumbrüche zwischen mit Semikolon abgeschlossenen Anweisungen entfernen?
Jona,
1

Python 3.2 (69)

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

PHP (keine eingebauten / eval) - 54

<foreach(explode(".",$argv[1])as$b)$a=@$a<<8|$b;echo$a;
Arnaud Le Blanc
quelle
Sollte dies nicht mit öffnen <?php, nicht nur <?
TRiG,
@TRiG, ​​ich glaube, Sie können den PHP-Öffnungsbegrenzer in der Konfigurationsdatei ändern. Nützlich in diesem Fall.
Xeoncross
@Xeoncross. Ah. Ordentlich. Das könnte ich eines Tages versuchen, nur um die Köpfe meiner Arbeitskollegen zu verwirren.
TRiG
1

Perl, 14 Zeichen:

sub _{unpack'L>',pop}

# Example usage
print _(10.10.104.36) # prints 168454180
Grimmig
quelle
5
Wie macht man das 14 Zeichen? Ich zähle 21.
Peter Taylor
1

C (gcc) -m32 / POSIX, 33 Bytes

f(a){inet_aton(a,&a);a=ntohl(a);}

Probieren Sie es online!

Auf einer Big-Endian - Plattform, können Sie einfach ein Makro mit definieren -Df=inet_atonfür 13 Bytes .

nwellnhof
quelle