Perl Weekly Challenge 272: Defang IP Address

These are some answers to the Week 272, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on June 9, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 1: Defang IP Address

You are given a valid IPv4 address.

Write a script to return the defanged version of the given IP address.

A defanged IP address replaces every period “.” with “[.]".

Example 1

Input: $ip = "1.1.1.1"
Output: "1[.]1[.]1[.]1"

Example 2

Input: $ip = "255.101.1.0"
Output: "255[.]101[.]1[.]0"

This the first time that I hear that an IP address could be "defanged."

Defang IP Address in Raku

To replace periods, ".", with "[.]", we can simply use a regex substitution. The only very slight difficulty is that a period or dot in a meta-character (a wild card matching any character), so to obtain literal matching of a period in the search pattern, we need to escape it (\.) or to quote it ('.').

sub defang-ip ($in is copy) {
    $in ~~ s:g/\./[.]/;
    return ~$in;
}

my @tests = "1.1.1.1", "255.101.1.0", "255.255.255.255";
for @tests -> $test {
    printf "%-16s => ", $test;
    say defang-ip $test;
}

This program displays the following output:

$ raku ./defang-ip.raku
1.1.1.1          => 1[.]1[.]1[.]1
255.101.1.0      => 255[.]101[.]1[.]0
255.255.255.255  => 255[.]255[.]255[.]255

Of course, the solution is simple enough to make a Raku one-line possible and easy:

$ raku -e 'my $in = shift @*ARGS; $in ~~ s:g/\./[.]/; say $in;' "255.101.1.0"
255[.]101[.]1[.]0

Defang IP Address in Perl

This is a port to Perl of the Raku program above, using the same regular expression substitution (and also with the need yo escape the period in the search pattern).

use strict;
use warnings;
use feature 'say';

sub defang_ip {
    $_[0] =~ s/\./[.]/g;
    return $_[0] ;
}

my @tests = ("1.1.1.1", "255.101.1.0", "255.255.255.255");
for my $test (@tests) {
    printf "%-16s => ", $test;
    say defang_ip $test;
}

This program displays the following output:

$ perl ./defang-ip.pl
1.1.1.1          => 1[.]1[.]1[.]1
255.101.1.0      => 255[.]101[.]1[.]0
255.255.255.255  => 255[.]255[.]255[.]255

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on June 16, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.