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

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:




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

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 :)


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).


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.


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

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


3

Golfscript - 21 Zeichen

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

+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

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

@ 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

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.


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
}

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


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}

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.


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

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

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

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


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

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

1

PHP (keine eingebauten / eval) - 54

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

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

5
Wie macht man das 14 Zeichen? Ich zähle 21.
Peter Taylor




Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.