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


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

I/O examples

input --> output

10001011111100010111110001111110 -->
00000000000000000000000000000000 -->
01111111000000000000000000000001 -->
11000000101010000000000111111111 -->


  • 6
    \$\begingroup\$ Input will always be a 32 bit binary number but your examples are binary lists. Is that also an acceptable input form? \$\endgroup\$ – Adám Jan 10 '20 at 12:49
  • 2
    \$\begingroup\$ Is it allowed to use a string as input instead of a list of binary digits? \$\endgroup\$ – Galen Ivanov Jan 10 '20 at 13:31
  • \$\begingroup\$ I have added a brief description of how the qaud-dotted notation is formed @LuisMendo. \$\endgroup\$ – mabel Jan 10 '20 at 13:31
  • \$\begingroup\$ @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. \$\endgroup\$ – mabel Jan 10 '20 at 13:33
  • 2
    \$\begingroup\$ I'm not clear, can we take in an actual number as input, like 2130706433 to give \$\endgroup\$ – xnor Jan 11 '20 at 4:00

43 Answers 43


05AB1E, 6 bytes


Try it online or verify all test cases.


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)

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


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 
B1 08       MOV  CL, 8          ; loop 8 bits 
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
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 
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 
75 D7       JNZ  BYTE_LOOP      ; continue byte loop 
C3          RET                 ; exit to DOS 


enter image description here

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


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!
  • \$\begingroup\$ 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? \$\endgroup\$ – Peter Cordes Jan 11 '20 at 20:13
  • \$\begingroup\$ 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. \$\endgroup\$ – Peter Cordes Jan 11 '20 at 20:24
  • \$\begingroup\$ 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). \$\endgroup\$ – Peter Cordes Jan 11 '20 at 20:27
  • 1
    \$\begingroup\$ @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! \$\endgroup\$ – 640KB Jan 11 '20 at 21:10
  • 1
    \$\begingroup\$ @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 (godbolt.org/z/6853--) if you have any thoughts or ideas. \$\endgroup\$ – 640KB Jan 13 '20 at 17:22

C (gcc), 48 bytes


Takes as input a 32-bit integer.

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

Try it online!

  • \$\begingroup\$ Missing semicolon in for loop. 48 bytes \$\endgroup\$ – girobuz Jan 12 '20 at 6:38

Jelly, 10 6 bytes


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
  • \$\begingroup\$ 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) \$\endgroup\$ – Jonathan Allan Jan 10 '20 at 14:52
  • \$\begingroup\$ Are you counting as a single byte? \$\endgroup\$ – chrylis -cautiouslyoptimistic- Jan 11 '20 at 7:13
  • 1
    \$\begingroup\$ @chrylis-onstrike- Jelly uses a custom code page to encode its characters. So, in this instance, yes, it's one byte. \$\endgroup\$ – AdmBorkBork Jan 12 '20 at 15:59

PHP, 26 bytes


Try it online!

OR taking input as a integer as an anonymous function :

PHP, 7 bytes


Try it online!

  • \$\begingroup\$ No need for bindec, $argn will be an integer. \$\endgroup\$ – Kerkouch Jan 18 '20 at 3:23
  • \$\begingroup\$ @kerkouch yes, that's true. I think that option was allowed after I posted the original answer. That simplifies this quite a bit. :) \$\endgroup\$ – 640KB Jan 18 '20 at 14:05

PowerShell, 46 bytes


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 ""+.

  • \$\begingroup\$ 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. \$\endgroup\$ – Malivil Jan 10 '20 at 15:45
  • 1
    \$\begingroup\$ @Malivil Dang, that's a side-effect of removing the "$( )" that I golfed. I'll put that back in. Thanks for the bug catch! \$\endgroup\$ – AdmBorkBork Jan 10 '20 at 16:06

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.


MathGolf, 6 bytes


Try it online.


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)

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

  • \$\begingroup\$ Using ⎕r on 'ing the entire list saves a byte \$\endgroup\$ – user41805 Jan 12 '20 at 7:57
  • \$\begingroup\$ @KritixiLithos How? \$\endgroup\$ – Adám Jan 12 '20 at 8:16
  • \$\begingroup\$ ' '⎕r'.'⍕256|... tio.run/… \$\endgroup\$ – user41805 Jan 12 '20 at 8:20
  • \$\begingroup\$ @KritixiLithos Oh right, for some reason I thought it was nested and would give too many spaces. \$\endgroup\$ – Adám Jan 12 '20 at 8:21

JavaScript (V8), 49 44 bytes

-5 bytes thanks to Arnauld


Try it online!

  • 1
    \$\begingroup\$ 44 bytes \$\endgroup\$ – Arnauld Jan 12 '20 at 10:37

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

public string I(long b)
    var x = new System.Net.IPAddress(b).ToString().Split('.');
    return string.Join(".", x);
  • 1
    \$\begingroup\$ by using lambdas, chaining and a hack for ToString() you can reduce it to 73 bytes \$\endgroup\$ – Expired Data Jan 13 '20 at 11:47
  • \$\begingroup\$ Thanks, @ExpiredData, totally forgot the string hack. \$\endgroup\$ – terrible-coder Jan 13 '20 at 15:59

Japt, 7 bytes

ò8 mÍq.

Try it here


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)

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.


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:
                       //     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
  • 1
    \$\begingroup\$ Since 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. \$\endgroup\$ – Holger Jan 13 '20 at 15:12
  • \$\begingroup\$ @Holger Oh, I didn't knew that. Thanks! :) \$\endgroup\$ – Kevin Cruijssen Jan 13 '20 at 16:56

Excel. 96 bytes


Python 3 (125 bytes)

def f(x):
    for j in range(4):
        if j<4:
    return y

Try it online

  • 1
    \$\begingroup\$ Hi. 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. \$\endgroup\$ – ElPedro Jan 11 '20 at 8:28
  • 1
    \$\begingroup\$ Here are a few hints for 80 bytes Try it online! \$\endgroup\$ – ElPedro Jan 11 '20 at 8:50
  • \$\begingroup\$ Thank you @ElPedro for the knowledge. \$\endgroup\$ – Merin Nakarmi Jan 15 '20 at 17:43
  • \$\begingroup\$ 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 :) \$\endgroup\$ – ElPedro Jan 15 '20 at 21:59
  • \$\begingroup\$ 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. \$\endgroup\$ – ElPedro Jan 15 '20 at 22:00

Red, 33 bytes

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

Try it online!

Takes the input as strings.


Burlesque, 13 bytes


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

Stax, 8 bytes


Run and debug it at staxlang.xyz!

Unpacked (9 bytes) and explanation:

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

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.

  • \$\begingroup\$ 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! \$\endgroup\$ – ElPedro Jan 11 '20 at 7:50
  • \$\begingroup\$ @ElPedro Awesome, great minds think alike! Good idea switching to 2 for str() to backticks save. :-) \$\endgroup\$ – Noodle9 Jan 11 '20 at 8:31

C (clang), 66 61 bytes


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


CJam, 10 bytes


Try it online!


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

Python 3, 47 bytes

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

Try it online!


PowerShell, 45 44 bytes


Try it online!

PowerShell, 45 bytes

Pure PowerShell. It does not use external libs.


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 '.')
  • 1
    \$\begingroup\$ Witchcraft! I can't even begin to understand how the second one works -- can you add an explanation? \$\endgroup\$ – AdmBorkBork Jan 12 '20 at 16:09
  • \$\begingroup\$ Thanks, O' Valley of Plenty. I've added explanation. \$\endgroup\$ – mazzy Jan 13 '20 at 8:17

Perl 5, 30 bytes


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.


Ruby, 37 34 bytes


Try it online!


Perl 6, 28 27 bytes

-1 byte thanks to Jo King

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

Try it online!


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:
  • \$\begingroup\$ [:#. 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 jsoftware.com/help/dictionary/d430.htm \$\endgroup\$ – user41805 Jan 16 '20 at 20:26
  • \$\begingroup\$ I can't spot the the possibility of using adverb infix in the code \$\endgroup\$ – Kamila Szewczyk Jan 17 '20 at 9:04

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

  • \$\begingroup\$ If REXX had a function that would go directly from binary to decimal I could chop 20 bytes off of this. \$\endgroup\$ – abricker Jan 17 '20 at 23:24

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.

: 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.
: 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 ;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.