Sorting IPv6
Friday, May 23, 2025
Recently, Chris Siebenmann was lamenting
the lack of a good command line way to sort IPv6
addresses.
This followed a post of his a few years ago about how sort -V
can
easily sort IPv4
addresses.
Since I had some fun talking about sorting Roman
numerals recently – and we have an extensive
standard
library – I
thought I’d talk about how you might solve this problem with
Factor.
As a reminder, IPv6 uses a 128-bit address space with more theoretical addresses than the older – but still quite commonly used – IPv4 32-bit address space.
The internal network address of your computer is sometimes referred to as
localhost or a loopback
address, and
represented as 127.0.0.1
in IPv4, or ::1
in IPv6. We have an
ip-parser
vocabulary with
words for parsing and manipulating IP addresses as well as IP network strings
written in CIDR
notation. We can
use these words to show how to translate these addresses to their byte
representation:
IN: scratchpad "127.0.0.1" parse-ipv4 .
B{ 127 0 0 1 }
IN: scratchpad "::1" parse-ipv6 .
{ 0 0 0 0 0 0 0 1 }
And, we could use that to sort a list of addresses pretty easily:
IN: scratchpad {
"127.0.0.1"
"1.1.1.1"
"8.8.8.8"
"192.168.10.40"
} [ parse-ipv4 ] sort-by .
{
"1.1.1.1"
"8.8.8.8"
"127.0.0.1"
"192.168.10.40"
}
IN: scratchpad {
"2620:0:1cfe:face:b00c::3"
"2001:4860:4860::8844"
"2620:0:ccc::2"
"::1"
"2001:4860:4860::8888"
} [ parse-ipv6 ] sort-by .
{
"::1"
"2001:4860:4860::8844"
"2001:4860:4860::8888"
"2620:0:ccc::2"
"2620:0:1cfe:face:b00c::3"
}
And so, now that some great feedback encouraged us to do command-line eval with auto-use? enabled, we can run this easily as a one-line script:
# make a file full of unsorted IPv6 addresses
$ cat <<EOF > ips.txt
2620:0:1cfe:face:b00c::3
2001:4860:4860::8844
2620:0:ccc::2
::1
2001:4860:4860::8888
EOF
# show that you can parse the file as strings
$ cat ips.txt | ./factor -e="read-lines ."
{
"2620:0:1cfe:face:b00c::3"
"2001:4860:4860::8844"
"2620:0:ccc::2"
"::1"
"2001:4860:4860::8888"
}
# sort and print the sorted output
$ cat ips.txt | ./factor -e="read-lines [ parse-ipv6 ] sort-by [ print ] each"
::1
2001:4860:4860::8844
2001:4860:4860::8888
2620:0:ccc::2
2620:0:1cfe:face:b00c::3
Pretty cool!