Convert a 32 bit binary IPv4 address to its quad-dotted notation

28

2

Challenge

Write a program or function that converts a 32 bit binary number to its quad-dotted decimal notation (often used for representing IPv4)

Quad-dotted decimal

A quad-dotted decimal is formed like so:

  1. Split the binary representation into its 4 individual bytes
  2. Convert each byte into denary
  3. place "." between each number

Example:

input:  10001011111100010111110001111110
step 1: 10001011 11110001 01111100 01111110
step 2:    139      241      124      126
step 3: 139.241.124.126

I/O examples

input --> output

10001011111100010111110001111110 --> 139.241.124.126
00000000000000000000000000000000 --> 0.0.0.0
01111111000000000000000000000001 --> 127.0.0.1
11000000101010000000000111111111 --> 192.168.1.255

Rules

mabel

Posted 2020-01-10T12:25:19.090

Reputation: 1 489

6Input will always be a 32 bit binary number but your examples are binary lists. Is that also an acceptable input form? – Adám – 2020-01-10T12:49:28.280

2Is it allowed to use a string as input instead of a list of binary digits? – Galen Ivanov – 2020-01-10T13:31:13.217

I have added a brief description of how the qaud-dotted notation is formed @LuisMendo. – mabel – 2020-01-10T13:31:50.783

@Adám this is actually how I meant for the challenge to be interpreted, but I guess I couldn't find the right word. I have added it as an acceptable input form, but left the 32 bit binary number as valid input also. – mabel – 2020-01-10T13:33:01.067

@GalenIvanov yes, I will edit the post to reflect this as well. – mabel – 2020-01-10T13:33:58.023

2I'm not clear, can we take in an actual number as input, like 2130706433 to give 127.0.0.1? – xnor – 2020-01-11T04:00:44.743

Is a trailing space or newline allowed? – ElPedro – 2020-01-11T09:05:46.343

seeing as I wrote that originally, I will allow it @xnor – mabel – 2020-01-11T13:07:44.110

that is fine @ElPedro – mabel – 2020-01-11T13:08:27.443

Answers

10

05AB1E, 6 bytes

4äC'.ý

Try it online or verify all test cases.

Explanation:

4ä       # Convert the (implicit) input-string into 4 equal-sized parts
  C      # Convert each part from binary to an integer
   '.ý  '# Join this list by "."
         # (after which the result is output implicitly)

Kevin Cruijssen

Posted 2020-01-10T12:25:19.090

Reputation: 67 575

19

x86-16 machine code, IBM PC DOS, 54 47 45 bytes

Binary:

00000000: be82 00b3 04b1 08ac d0d8 d0d4 e2f9 8ac4  ................
00000010: 41d4 0a50 8ac4 84c0 75f6 580c 30b4 0ecd  A..P....u.X.0...
00000020: 10e2 f74b 7406 b02e cd10 ebd9 c3         ...Kt........

Build and test BIN2IP.COM using xxd -r from above.

Unassembled listing:

BE 0082     MOV  SI, 82H        ; command line input address
B3 04       MOV  BL, 4          ; loop 4 bytes 
        BYTE_LOOP:
B1 08       MOV  CL, 8          ; loop 8 bits 
        BIT_LOOP: 
AC          LODSB               ; load next bit char into AL 
D0 D8       RCR  AL, 1          ; put LSB of char into CF 
D0 D4       RCL  AH, 1          ; put CF into LSB of byte value, then shift left
E2 F9       LOOP BIT_LOOP       ; continue bit loop 
8A C4       MOV  AL, AH         ; put byte result into AL
        GET_DIGIT: 
D4 0A       AAM                 ; byte divide by 10, AH = AL / 10, AL = AL % 10 
50          PUSH AX             ; save remainder in AL on stack 
8A C4       MOV  AL, AH         ; put quotient back into AL 
41          INC  CX             ; increment decimal digit count 
D4 C0       TEST AL, AL         ; quotient = 0? 
75 F6       JNZ  GET_DIGIT      ; if not, continue looping 
        PRINT_DIGIT: 
58          POP  AX             ; restore digit in AL 
0C 30       OR   AL, '0'        ; ASCII convert              
B4 0E       MOV  AH, 0EH        ; BIOS write char function   
CD 10       INT  10H            ; write to console 
E2 F7       LOOP PRINT_DIGIT    ; loop until done 
4B          DEC  BX             ; is last byte? 
74 06       JZ   END_LOOP       ; if so, don't display a '.' 
B0 2E       MOV  AL, '.'        ; otherwise display '.'
CD 10       INT  10H            ; write to console 
        END_LOOP:
75 D7       JNZ  BYTE_LOOP      ; continue byte loop 
C3          RET                 ; exit to DOS 

Output:

enter image description here

A standalone PC DOS executable. Input is command line, output to console.

Notes:

The "interesting part" (converting binary string to bytes) is about 15 bytes, whereas the rest of code is writing the itoa() function to convert binary bytes into a decimal string representation for display.

  • -2 bytes eliminating unnecessary PUSH/POP thx to @PeterCordes!

640KB

Posted 2020-01-10T12:25:19.090

Reputation: 7 149

dec cx / jz end_loop could be re-arranged using a loop instruction that either falls through to a ret or jumps forward to mov al/int 10h/jmp byte_loop, for a net saving of I think 1 byte, from replacing dec cx/jcc with loop. Or maybe use DI for that loop counter instead of CX, avoiding push/pop? – Peter Cordes – 2020-01-11T20:13:26.877

BTW, several size-neutral changes that would make it more efficient (especially on modern CPUs): shr al,1 to shift the low bit into CF, not RCR. You don't need an input dependency on FLAGS. (Or hmm, possibly even scasb with AL='1' instead of loading, but that would invert). adc ah,ah can be 1 uop, RCL isn't. Also, test reg,reg/jcc is more efficient than or reg,reg, and the same size. I think the inefficient or idiom comes from 8080 ORA A, which didn't have an opcode that only set flags.

– Peter Cordes – 2020-01-11T20:24:13.100

The question allows input as a 32-bit binary integer so you could just write a function that takes that (in memory pointed to by DS:SI if you want), instead of converting from a base 2 string. Also, instead of push/pop for digit-order, you could maybe store backwards into a buffer, creating a $-terminated string, and when you're done you have a pointer to the first byte. How do I print an integer in Assembly Level Programming without printf from the c library? shows the algorithm (and using a Linux write system call on it).

– Peter Cordes – 2020-01-11T20:27:12.680

or al,al takes the same number of clock cycles on 8086, but read my linked answer for why it's slower on modern x86. (Can't macro-fuse with JCC, and introduces an extra operation in the dependency chain for that register for later readers). For the shifts, shr al is the semantically simpler operation, and for performance has no flag inputs. Also, rotate-through-carry is never a single uop on modern CPUs but ADC can be (on Intel Broadwell and later, and on all AMD), so generally prefer adc reg,reg over of rcl reg,1 unless you need its slightly different flag output. – Peter Cordes – 2020-01-11T20:56:57.940

re: replacing dec cx / jz with LOOP: https://godbolt.org/z/BBkteF is NASM source for my 9-byte sequence that is equivalent to your 10-byte sequence. My idea did work out, using LOOP to jump forward or fall through to a ret.

– Peter Cordes – 2020-01-11T20:58:37.373

I'm not sure the ideas are compatible; if you use CX for the outer loop, you can't take advantage of loop for the inner bit-loop without spending 2 bytes on push/pop. Since using BX saved 2 bytes (because you could take advantage of BH being known zero) vs. my idea only saving one, I think using BX wins. – Peter Cordes – 2020-01-11T21:03:55.840

1@PeterCordes yes, I just tried and that's what's happening. I was doing two different LOOPs on the "inner" loop, and since I can count on CX being 0 at the end of the first, I used it as the counter for decimal digits and looped again. Unfortunately DEC / JNZ is 1 byte more than LOOP so my gain there offsets the BX outer loop gain. So, yes, BX would seem to win but it was a great idea and fun exercise to go through! – 640KB – 2020-01-11T21:10:34.133

re: mov + set flags. Not in less than 4 bytes, unless there's a clever way to zero AL first. Then you could do or al, ah to set AL=AH|0 = AH, and set flags. If AH could only have a couple possible values, mov al, '0' / or al, ah and then branch on PF might be possible to fold in the later OR. ARM has mov-and-set-flags; x86 doesn't. – Peter Cordes – 2020-01-11T21:10:42.620

One of my favourite abuses of LOOP is inc cx / loop target = 3 byte version of test cx,cx / jnz target. (In 16 and 32-bit mode). (Invented for this answer. I assume I'm not the first inventor of this trick but I don't look at a lot of legacy code optimized for code-size over performance.)

– Peter Cordes – 2020-01-11T21:16:09.933

After div, FLAGS are "undefined". I haven't checked what actually happens on any real CPUs or emulators. Taking advantage of implementation-specific behaviour is generally allowed in code-golf answers, if you want to do so. But then you need a divisor in a register or memory, costing at least 2 bytes for a mov r8,10

– Peter Cordes – 2020-01-11T21:20:12.250

x86 doesn't have conditional ret, and https://nasm.us/doc/nasmdocb.html doesn't seem to have any undocumented opcodes for it. ARM32 can predicate anything, including bx lr, but on x86 JCXZ, LOOP, LOOPE/LOOPNE, and JCC are the only conditional jumps, if you don't count stuff like TSX xbegin / xabort. e.g. Does an aborted xbegin transaction restore the stack context that existed at the xbegin start?. But that's hardly useful golfing.

– Peter Cordes – 2020-01-11T21:29:20.250

1

@PeterCordes I experimented with writing in reverse to a string buffer, and was only able to get it down to 48 bytes. Here's the scratchpad (https://godbolt.org/z/6853--) if you have any thoughts or ideas.

– 640KB – 2020-01-13T17:22:57.743

That idea probably works better for a function that takes a pointer arg and returns a pointer to the start of the string, so you get to skip actually printing. And can maybe justify not storing a terminator yourself, leaving it up to the caller to choose to 0-terminate, '$'-terminate, or just calculate a length from end-start and use it as explicit-length. – Peter Cordes – 2020-01-13T18:23:04.607

8

C (gcc), 48 bytes

i;f(n){for(i=4;i--;)printf(".%hhu"+i/3,n>>i*8);}

Takes as input a 32-bit integer.

Thanks to ceilingcat and gastropner for getting this answer where it is now!

Try it online!

S.S. Anne

Posted 2020-01-10T12:25:19.090

Reputation: 1 161

Missing semicolon in for loop. 48 bytes

– girobuz – 2020-01-12T06:38:53.183

7

Jelly, 10 6 bytes

s8Ḅj“.

Try it online!

s            Slice input list
 8           into size 8 chunks
  Ḅ          Convert from binary list to integer
   j“.       Join with dots as the separator
             Implicit output

AdmBorkBork

Posted 2020-01-10T12:25:19.090

Reputation: 41 581

If you use (character) rather than (start list of characters) this would be a Link rather than a full program (although submission may want to ba a full-program anyway, since the Link result is not just a list of characters, so we may prefer the implicit printing) – Jonathan Allan – 2020-01-10T14:52:44.020

Are you counting as a single byte? – chrylis -on strike- – 2020-01-11T07:13:49.377

1

@chrylis-onstrike- Jelly uses a custom code page to encode its characters. So, in this instance, yes, it's one byte.

– AdmBorkBork – 2020-01-12T15:59:10.617

5

PHP, 26 bytes

<?=long2ip(bindec($argn));

Try it online!

OR taking input as a integer as an anonymous function :

PHP, 7 bytes

long2ip

Try it online!

640KB

Posted 2020-01-10T12:25:19.090

Reputation: 7 149

No need for bindec, $argn will be an integer. – Kerkouch – 2020-01-18T03:23:15.130

@kerkouch yes, that's true. I think that option was allowed after I posted the original answer. That simplifies this quite a bit. :) – 640KB – 2020-01-18T14:05:37.537

4

PowerShell, 46 bytes

""+[IPAddress]"$([Convert]::ToInt64($args,2))"

Try it online!

First takes input $args binary string and [System.Convert]s it into Int64. Uses the .NET type call [System.Net.Ipaddress] to parse that Int64 into an IPAddress object, then coerces the .IPAddressToString() method by prepending ""+.

AdmBorkBork

Posted 2020-01-10T12:25:19.090

Reputation: 41 581

Unfortunately on systems that are LittleEndian (like TIO and most computers... I think?) this parses the binary backwards so the IP in your TIO link has the quads in reverse order. – Malivil – 2020-01-10T15:45:13.273

1@Malivil Dang, that's a side-effect of removing the "$( )" that I golfed. I'll put that back in. Thanks for the bug catch! – AdmBorkBork – 2020-01-10T16:06:19.063

4

Python 2, 47 bytes

f=lambda n,k=-2:k*`n`or f(n>>8,k+1)+'.'+`n%256`

Try it online!


Python 3, 46 bytes

lambda n:('.%d'*4%(*n.to_bytes(4,"big"),))[1:]

Try it online!

Shaving a byte from David Foerster's to_bytes solution using string formatting.

xnor

Posted 2020-01-10T12:25:19.090

Reputation: 115 687

3

APL (Dyalog Unicode), 20 19 bytesSBCS

-1 thanks to Kritixi Lithos.

Full program. Prompts for 32-bit integer, optionally as list of bits.

' '⎕R'.'⍕256|83⎕DR⎕

Try it online!

 console prompt for numeric input

83⎕DR interpret the bits of that data as 8-bit integers (internal Data Representation type 3)

256| convert to unsigned integers (lit. 256-mod of that)

 stringify (makes space-separated string)

' '⎕R'.'Replace spaces with dots

Adám

Posted 2020-01-10T12:25:19.090

Reputation: 37 779

Using ⎕r on 'ing the entire list saves a byte – user41805 – 2020-01-12T07:57:27.527

@KritixiLithos How? – Adám – 2020-01-12T08:16:19.543

@KritixiLithos Oh right, for some reason I thought it was nested and would give too many spaces. – Adám – 2020-01-12T08:21:47.983

3

MathGolf, 6 bytes

8/å'.u

Try it online.

Explanation:

8/       # Split the (implicit) input-string into parts of size 8
  å      # Convert each part from a binary-string to an integer
   '.u  '# Join by "."
         # (after which the entire stack joined together is output implicitly)

Kevin Cruijssen

Posted 2020-01-10T12:25:19.090

Reputation: 67 575

3

JavaScript (V8), 49 44 bytes

-5 bytes thanks to Arnauld

s=>s.match(/.{8}/g).map(x=>'0b'+x|0).join`.`

Try it online!

Expired Data

Posted 2020-01-10T12:25:19.090

Reputation: 3 129

144 bytes – Arnauld – 2020-01-12T10:37:00.067

3

C#7+, 117 73 bytes

s=>string.Join('.',(new System.Net.IPAddress(s)+"").Split('.').Reverse())

Accepts the bit representation of an IP address to transform it into a four-number notation, converts it to a string array, reverses the elements to account for the endianness differences of machines, then joins them together again with a dot.

Try it online!

  • Reduced to 73 bytes by utilizing the string hack and chaining (c/o @Expired Data)

Initial answer, 117 bytes

string I(long b){var x=new System.Net.IPAddress(b).ToString().Split('.');Array.Reverse(x);return string.Join(".",x);}

Use it like:

void Main()
{
    Console.WriteLine(I(0b_10001011111100010111110001111110));
}

public string I(long b)
{
    var x = new System.Net.IPAddress(b).ToString().Split('.');
    Array.Reverse(x);
    return string.Join(".", x);
}

terrible-coder

Posted 2020-01-10T12:25:19.090

Reputation: 41

1

by using lambdas, chaining and a hack for ToString() you can reduce it to 73 bytes

– Expired Data – 2020-01-13T11:47:36.640

Thanks, @ExpiredData, totally forgot the string hack. – terrible-coder – 2020-01-13T15:59:37.030

2

Java 9, 97 94 92 81 bytes

s->{for(int i=0;i<32;)System.out.print((i>0?".":"")+Long.parseLong(s,i,i+=8,2));}

-2 bytes thanks to @AZTECCO.
-11 bytes thanks to @Holger by combining the Long.parseLong(s.substring(i,i+=8),2) into Long.parseLong(s,i,i+=8,2).

Try it online.

Explanation:

s->{                   // Method with String parameter and no return-type
  for(int i=0;i<32;)   //  Loop `i` in the range [0, 32):
    System.out.print(  //   Print:
      (i>0?            //    If `i` is larger than 0 (so it's not the first iteration):
        "."            //     Print a dot
       :               //    Else:
        "")            //     Print nothing instead
      +                //    Appended with:
       Long.parseLong(s,i,i+=8,2));}
                       //     A substring of the input `s` from index `i` to `i+8`,
                       //     (and increase `i` by 8 for the next loop iteration)
                       //     Converted from binary-String to integer

Kevin Cruijssen

Posted 2020-01-10T12:25:19.090

Reputation: 67 575

1Since Java 9, you can use Long.parseLong(s,i,i+=8,2) which will not only improve it from a golfing point of view, even the performance will be better as it saves the substring operations. – Holger – 2020-01-13T15:12:04.373

@Holger Oh, I didn't knew that. Thanks! :) – Kevin Cruijssen – 2020-01-13T16:56:10.427

2

Japt, 7 bytes

ò8 mÍq.

Try it here

Shaggy

Posted 2020-01-10T12:25:19.090

Reputation: 24 623

2

Python 3 (125 bytes)

def f(x):
    y=''
    for j in range(4):
        y+=str(int(x[j*8:j*8+8],2))
        if j<4:
            y+="."
    return y

Try it online

Merin Nakarmi

Posted 2020-01-10T12:25:19.090

Reputation: 247

1Hi. Small problem in that this outputs an extra "." at the end. Easily fixed by changing j<4 to j<3. Also we normally count bytes and not characters and according to TIO this is 125 bytes. – ElPedro – 2020-01-11T08:28:36.187

1

Here are a few hints for 80 bytes Try it online!

– ElPedro – 2020-01-11T08:50:19.380

Thank you @ElPedro for the knowledge. – Merin Nakarmi – 2020-01-15T17:43:24.563

My pleasure, however there are a couple more golfs that I didn't mention. I'll leave those for you to find. Since OP has said that trailing space is alowed then you can save at least 6 more. Have fun :) – ElPedro – 2020-01-15T21:59:53.360

BTW, even if you don't use the hints, you should really update the answer to correct the identified problem and please feel free to post my suggestions as an improved answer. – ElPedro – 2020-01-15T22:00:17.960

2

k4, 18 17 bytes

saved a byte by expressing in composed form instead of as a lambda:

("."/:$2/:'4 0N#)

original explanation: output is string, quad-dot decimal not supported by k

{"."/:$2/:'4 0N#x}

{                } /lambda with implicit arg x
           4 0N#x  /cut x into 4 pieces
       2/:'        /convert each piece to decimal
      $            /stringify
 "."/:             /join with .

called on 2 binaries:

{"."/:$2/:'4 0N#x}'(10001011111100010111110001111110b;11000000101010000000000111111111b)
("139.241.124.126";"192.168.1.255")

scrawl

Posted 2020-01-10T12:25:19.090

Reputation: 1 079

2

Excel. 96 bytes

=BIN2DEC(LEFT(A1,8))&"."&BIN2DEC(MID(A1,9,8))&"."&BIN2DEC(MID(A1,17,8))&"."&BIN2DEC(RIGHT(A1,8))

Wernisch

Posted 2020-01-10T12:25:19.090

Reputation: 2 534

1

Perl 5, 30 bytes

s/.{8}/oct("0b$&").'.'/ge;chop

Try it online!

Search-replaces with regexp that takes eight bits (0 or 1) at a time and converts them to their decimal representation with . placed after each, but chops off the last . char. Using a function named oct here seems counter-intuitive since the input string isn't octal. But when the given string starts with 0b the rest is read as the binary string it is.

Kjetil S.

Posted 2020-01-10T12:25:19.090

Reputation: 1 049

1

Red, 33 bytes

func[n][to 1.1.1 debase/base n 2]

Try it online!

Takes the input as strings.

Galen Ivanov

Posted 2020-01-10T12:25:19.090

Reputation: 13 815

1

Python 2, 81 \$\cdots\$ 58 55 bytes

lambda s:'.'.join(`int(s[i:i+8],2)`for i in(0,8,16,24))

Try it online!

Saved 3 bytes thanks to ElPedro!!!

Lambda function that takes a string of 32 "0"s and "1"s.

Noodle9

Posted 2020-01-10T12:25:19.090

Reputation: 2 776

Ha, just came up wth the same thing! If you switch to Python 2 you can use backticks instead of str() to save 3 more Try it online!

– ElPedro – 2020-01-11T07:50:01.447

@ElPedro Awesome, great minds think alike! Good idea switching to 2 for str() to backticks save. :-) – Noodle9 – 2020-01-11T08:31:38.157

1

Burlesque, 13 bytes

8co{b2}]m'.IC

Try it online!

8co    #Break into chunks 8 long
{b2}]m #Read each chunk as base-2 and turn to string
'.IC   #Intercalate "." between each and collapse

DeathIncarnate

Posted 2020-01-10T12:25:19.090

Reputation: 916

1

Stax, 8 bytes

Ç∩0&→Ö¡ 

Run and debug it at staxlang.xyz!

Unpacked (9 bytes) and explanation:

8/{|Bm'.*
8/           Split into length-8 chunks. 4M would work just as well.
  {|Bm       Convert each chunk to decimal
      '.*    Join with .

Khuldraeseth na'Barya

Posted 2020-01-10T12:25:19.090

Reputation: 2 608

1

Perl 6, 28 27 bytes

-1 byte thanks to Jo King

{chop S:g/.**8/{:2(~$/)}./}

Try it online!

nwellnhof

Posted 2020-01-10T12:25:19.090

Reputation: 10 037

Using chop is one byte shorter

– Jo King – 2020-01-14T01:39:16.513

1

Ruby, 37 34 bytes

->b{(-3..0).map{|w|255&b<<w*8}*?.}

Try it online!

G B

Posted 2020-01-10T12:25:19.090

Reputation: 11 099

1

CJam, 10 bytes

l~8/2fb'.*

Try it online!

Explanation

l~    e# Read a line and evaluate it. Pushes list to the stack
8/    e# Split into sublists of 8 elements each. Gives list of sublists
2fb   e# Map "base conversion" with extra parameter 2 over the list of sublists
'.*   e# Join sublists with character ".". Implicitly display

Luis Mendo

Posted 2020-01-10T12:25:19.090

Reputation: 87 464

1

C (clang), 66 61 bytes

i;g(*m){for(i=32;i--;)*++m+=i%8?*m*2:!printf(".%d"+i/24,*m);}

Try it online!

Input as an array of integers (bits)

Adds current number shifted to the next. Every 8 bits it prints instead of adding.

Saved 5 thanks to @gastropner and @ceilingcat

AZTECCO

Posted 2020-01-10T12:25:19.090

Reputation: 2 441

163 bytes – gastropner – 2020-01-11T01:51:34.173

1

PowerShell, 45 44 bytes

$args|%{$r+=+$r+"$_"}
[ipaddress]::Parse($r)

Try it online!


PowerShell, 45 bytes

Pure PowerShell. It does not use external libs.

($args|%{($r=2*$r%256+"$_")[++$i%8]})-join'.'

Try it online!

Unrolled and commented:

$bytes = $args|%{           # $args is array on character 48 or 49 (bits)
    $r = 2 * $r             # one bit shift left
                            # the first operand is integer, so Powershell converts the second operand to an integer
    $r = $r % 256           # bitwise and 0xFF
    $digit = "$_"           # convert a char 48, 49 to string "0" or "1" respectively
    $r = $r + $digit        # add a digit
                            # the first operand is integer, so Powershell converts the second operand to an integer
    # now $r is a byte containing 8 bits to the left of the current one

    $index = ++$i % 8       # 1,2,3,4,5,6,7,0, 1,2,3,4,5,6,7,0, ...
    ($r)[$index]            # represent $r as an array; take an element of this array
                            # index 0 will give $r, other indexes will give $null
                            # Powershell outputs non $null values only
                            # Compare to `Wrtie-Output ($r)[$index]`
}
# now $bytes is array of not $null elements
Write-Output ($bytes -join '.')

mazzy

Posted 2020-01-10T12:25:19.090

Reputation: 4 832

1Witchcraft! I can't even begin to understand how the second one works -- can you add an explanation? – AdmBorkBork – 2020-01-12T16:09:25.547

Thanks, O' Valley of Plenty. I've added explanation. – mazzy – 2020-01-13T08:17:17.347

1

Python 3, 47 bytes

lambda n:".".join(map(str,n.to_bytes(4,"big")))

Try it online!

David Foerster

Posted 2020-01-10T12:25:19.090

Reputation: 260

1

Forth (gforth), 130 bytes.

Requires a Forth that starts in decimal mode, works with gforth.

: p . 8 emit ." ." ;
: d dup 255 and swap ;      
: r 8 rshift d ;
: q 32 2 base ! word number drop d r r r drop decimal p p p . ;

Try it online!

Usage: q 10001011111100010111110001111110 [enter]

Deobfuscated version (or how I would really do it)

\ Forth program to convert a binary IP address to dotted decimal notation.

decimal
: binary   2 base ! ;

\ Get the binary string and convert to a number.
: getbin   32 binary word number drop ;

\ Shift and mask the byte we are interested in. Put all 4 on the stack.
hex
: mask   rshift dup ff and ;
: quad4   dup ff and swap ;
: quad   8 mask swap ;
: 3more   quad quad quad ;

\ Print a quad, backspace over it's trailing space, print a dot.
: .quad   . 8 emit ." ." ;

\ Print all 4 quads in decimal.
: .4quads   decimal .quad .quad .quad . ;

\ Get binary number, chop it up into 4 quads, print in decimal.
: qdot   getbin quad4 3more drop .4quads ;

abricker

Posted 2020-01-10T12:25:19.090

Reputation: 61

1

REXX, 91 bytes

PARSE ARG WITH 1 A 9 B 17 C 25 D
SAY X2D(B2X(A))'.'X2D(B2X(B))'.'X2D(B2X(C))'.'X2D(B2X(D))

Online REXX interpreter

abricker

Posted 2020-01-10T12:25:19.090

Reputation: 61

If REXX had a function that would go directly from binary to decimal I could chop 20 bytes off of this. – abricker – 2020-01-17T23:24:37.053

1

J, 18 bytes

' .'rplc~&":_8#.\]

Try it online!

Old answer

-2 thanks to Kritixi Lithos

' .'rplc~&":2#.4 8$]

Try it online!

My first answer in a non-esolang! (kinda). The way this answer works is pretty simple. Let's look first at a non-tacit form of this expression:

(":#.(4 8 $ n))rplc' .'

Assuming that (for instance) n is:

n =: 1 0 0 0 1 0 1 1 1 1 1 1 0 0 0 1 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 

The expression 4 8 $ n is equal to:

1 0 0 0 1 0 1 1
1 1 1 1 0 0 0 1
0 1 1 1 1 1 0 0
0 1 1 1 1 1 1 0

Then, the #. verb is applied over the matrix, yielding the following result:

139 241 124 126

The resulting list is stringified using ":, and using rplc every space in the string representation of list is swapped to a dot, yielding the final form:

139.241.124.126

Krzysztof Szewczyk

Posted 2020-01-10T12:25:19.090

Reputation: 3 819

[:#. can become 2#., and you can also remove the cap in rplc~[:": with rplc~&":. Also 2#.4 8$] can become shorter with the adverb infix https://www.jsoftware.com/help/dictionary/d430.htm – user41805 – 2020-01-16T20:26:10.707

I can't spot the the possibility of using adverb infix in the code – Krzysztof Szewczyk – 2020-01-17T09:04:24.363

1

Julia, 58 52 bytes

x->join(parse.(Int,x[n:n+7] for n=1:8:25;base=2),:.)

Takes the input string and uses a comprehension to create an array of the 8 bits. Then parses each element (via 'broadcasting' with the . into an Int. Last step is to join with the period.

Reductions per comments below:

  • 4 byte reduction by simplifying the comprehension indexing
  • 1 byte reduction in changing the separator from a string to a symbol (which join converts into a string upon joining with the integers)

Alec

Posted 2020-01-10T12:25:19.090

Reputation: 111

x->join(parse.(Int,(x[n:n+7] for n=1:8:25),base=2),".") for 55 bytes - from a suggested edit. – Lyxal – 2020-02-07T11:05:20.160

Using 52 bytes: x->join(parse.(Int,x[n:n+7] for n=1:8:25;base=2),:.) – user3263164 – 2020-02-07T12:35:56.587

0

Batch, 56 bytes

@for /f "tokens=2" %%f in ('ping %1')do @echo %%f&exit/b

Takes input as the first command-line argument. Somewhat slow, but -n1 -w1 can be added to the ping command to speed it up a bit.

Neil

Posted 2020-01-10T12:25:19.090

Reputation: 95 035

0

GolfScript, 20 bytes

8/{1/{~}%2base}%'.'*

Try it online!

Explanation

8/                   # Split into size 8 chunks
  {           }%     # For-each over the chunks
   1/                # Split into size-1 chunks
     {~}%            # Convert each from string to number
         2base       # Convert to base 10
                '.'* # Join with dots

user85052

Posted 2020-01-10T12:25:19.090

Reputation:

0

[C (gcc clang)], 97 85 77 bytes

x;f(*s){x=strtoul(s,s,2);printf("%hhu.%hhu.%hhu.%hhu\n",x>>24,x>>16,x>>8,x);}

Try it online!

This version takes a string as input. 8 bytes shaved off thanks to JL2210!

G. Sliepen

Posted 2020-01-10T12:25:19.090

Reputation: 580

1You can remove the &255 by using %hhu. – S.S. Anne – 2020-01-11T00:43:45.740

I think the final newline is not required. To leave it out saves 2 bytes. – David Foerster – 2020-01-13T01:17:53.333

0

Alchemist, 97 bytes

_->3a+7b+i
i+n->i+m
i+0n->j+In_n
j+m->j+2n
j+0m+b->i
j+0m+0b->k+Out_n
k+n->k
k+0n+a->7b+i+Out_"."

Try it online!

a and b count down the bytes and bits remaining, respectively. i, j, and k are phase/step atoms. The current byte is stored in n, with temporary storage in m.

Nitrodon

Posted 2020-01-10T12:25:19.090

Reputation: 9 181

0

Pyth, 10 9 bytes

j\.iR2cz8

Try it online!

Chops input into pieces of length 8 (cz8), then maps int(x, 2) over the result (iR2). Then just joins those with a dot separator (j\.).

-1 by using a more specialized map (R) instead of the generic m.

randomdude999

Posted 2020-01-10T12:25:19.090

Reputation: 789

0

SmileBASIC, 49 bytes

INPUT X
RGBREAD X OUT A,B,C,D?A;".";B;".";C;".";D

Takes a decimal integer as input

the RGB and RGBREAD functions were designed to convert between 32 bit ARGB color values and separate 8 bit channels

12Me21

Posted 2020-01-10T12:25:19.090

Reputation: 6 110

0

Python 3, 44 bytes

Another one using to_bytes trick, but this one also uses f-strings.

'.'.join(f"{b}"for b in n.to_bytes(4,"big"))

Dmitry Rubanovich

Posted 2020-01-10T12:25:19.090

Reputation: 101

2You don't appear to be doing any input or output. To be valid, you should either make this a function by prepending lambda n: to the front, or mark this as REPL and change n to int(input()) – Jo King – 2020-01-14T00:47:13.090

0

Haskell, 52 bytes

s n|(y,x)<-divMod n 256=concat[s y++"."|y>0]++show x

Try it online!

Takes input as number. Repeatedly divMods by 256 until the div is zero.

Post Rock Garf Hunter

Posted 2020-01-10T12:25:19.090

Reputation: 55 382

0

Perl, 33 bytes

$_=join'.',unpack'C4',pack'B*',$_

Try it online!

Read in right-to-left order:

  1. Encode input using pack
  2. Extract four unsigned bytes with unpack
  3. Intercalate . separators with join

Greg Bacon

Posted 2020-01-10T12:25:19.090

Reputation: 111

0

Ruby -p, 34 bytes

Replaces each 8-character subsequence with its decimal conversion plus a dot, then removes the last dot.

gsub(/.{8}/){"#{$&.to_i 2}."}
chop

Try it online!

Value Ink

Posted 2020-01-10T12:25:19.090

Reputation: 10 608

0

Fortran (GFortran), 58 bytes

integer i(4)                 !Declare 4 int array
read('(4B8)'),i              !Read as 4 length 8 binary numbers
print('(3(i0,"."),i0)'),i    !Print as 3 auto-length ints followed by a '.' and then the last int
end

Try it online!

DeathIncarnate

Posted 2020-01-10T12:25:19.090

Reputation: 916

0

Lua, 82 bytes

print(io.read():gsub(("%d"):rep(8),function(n)return'.'..tonumber(n,2)end):sub(2))

Try it online!

Takes input from stdin and writes to stdout. Works on Lua 5.0+.

This works by using string.gsub's ability to replace matches using a helper function. The function used here replaces a string of eight binary digits with a . followed by the digits in decimal. The :sub(2) at the end removes the extraneous . at the beginning of the resulting string.

Un-golfed version + extra explanation:

print(                                       -- print
    string.sub(                              --  substring
        string.gsub(                         --   replace
            io.read(),                       --    in string
            "%d%d%d%d%d%d%d%d",              --    replace
            function(n)                      --    with
                return                       --     result of
                    '.' ..                   --      concatenate with
                    tonumber(                --      string to number
                        n,                   --       convert this
                        2                    --       with base
                    )
            end
        ),
        2                                    --   starting at character (1-index)
    )
)

JackMacWindows

Posted 2020-01-10T12:25:19.090

Reputation: 21