I recently learnt about ipcalc, a nifty tool that helps visualize basic IPv4 concepts. I think writing a very basic clone can help ingrain these concepts in one’s brain.

Here’s my attempt in q:

pow:{(*/)y#x}
rp:{x,(y-count x)#" "} / right pad
is:{[n;s](n sublist s)," ",n _ s} / insert space
bv2i:sv[0b;] / boolean vector to integer
i2bv:vs[0b;] / integer to boolean vector
ip2dn:{"."sv string"h"$0x0 vs x} / ip to dot notation
ip2class:{$[128>c:first 0x0 vs x;"A";192>c;"B";224>c;"C";240>c;"D";"E"]}
ip2bdn:{[nm;ip]is[nm+floor nm%8;"."sv raze each string i2bv each 0x0 vs ip]} / ip to binary dot notation
ipcLine:{rp[x;11],color[`blue;rp[y;21]],z}
color:{[c;s]"\033[0;",((`red`orange`blue`purple!string 31 33 34 35)c),"m",s,"\033[0m"}
main:{
  ip:0x0 sv "x"$"H"$"." vs first "/" vs .z.x 0;
  nm:"H"$last "/" vs .z.x 0;
  nmIp:bv2i (nm#1b),(32-nm)#0b;
  wc:bv2i (nm#0b),(32-nm)#1b;
  nIp:bv2i i2bv[nmIp]and i2bv ip;
  bIp:bv2i i2bv[nIp]or i2bv wc;
  hmin:bv2i i2bv[nIp]or (31#0b),1b;
  hmax:bv2i i2bv[bIp]and (31#1b),0b;
  ipclass:ip2class ip;
  -1 ipcLine["Address:";ip2dn ip;color[`orange;ip2bdn[nm;ip]]];
  -1 ipcLine["Netmask:";ip2dn[nmIp]," = ",string nm;color[`red;ip2bdn[nm;nmIp]]];
  -1 ipcLine["Wildcard:";ip2dn wc;color[`orange;ip2bdn[nm;wc]]];
  -1 "=>";
  -1 ipcLine["Network:";ip2dn[nIp],"/",string nm;color[`purple;cb#nmBIp],color[`orange;(cb:("ABCDE"!1 2 3 4 4)ipclass)_ nmBIp:ip2bdn[nm;nIp]]];
  -1 ipcLine["HostMin:";ip2dn hmin;color[`orange;ip2bdn[nm;hmin]]];
  -1 ipcLine["HostMax:";ip2dn hmax;color[`orange;ip2bdn[nm;hmax]]];
  -1 ipcLine["Broadcast:";ip2dn bIp;color[`orange;ip2bdn[nm;bIp]]];
  -1 ipcLine["Hosts/Net:";string pow[2;32-nm]-2;color[`purple;" Class ",string ipclass]];
  -1 "";}

main[]
\\

some sample outputs:

$ q ipcalc.q 12.7.149.12/26 -q
Address:   12.7.149.12          00001100.00000111.10010101.00 001100
Netmask:   255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Wildcard:  0.0.0.63             00000000.00000000.00000000.00 111111
=>
Network:   12.7.149.0/26        00001100.00000111.10010101.00 000000
HostMin:   12.7.149.1           00001100.00000111.10010101.00 000001
HostMax:   12.7.149.62          00001100.00000111.10010101.00 111110
Broadcast: 12.7.149.63          00001100.00000111.10010101.00 111111
Hosts/Net: 62                    Class A

$ q ipcalc.q 216.163.54.22/28 -q
Address:   216.163.54.22        11011000.10100011.00110110.0001 0110
Netmask:   255.255.255.240 = 28 11111111.11111111.11111111.1111 0000
Wildcard:  0.0.0.15             00000000.00000000.00000000.0000 1111
=>
Network:   216.163.54.16/28     11011000.10100011.00110110.0001 0000
HostMin:   216.163.54.17        11011000.10100011.00110110.0001 0001
HostMax:   216.163.54.30        11011000.10100011.00110110.0001 1110
Broadcast: 216.163.54.31        11011000.10100011.00110110.0001 1111
Hosts/Net: 14                    Class C

go write your own now…

references