Coding/Blog challenge 8

Coding/Blog challenge 8

It has been a couple of days since my last challenge, I've had to manage this challenge with a busy schedule. I also had to do a lot of research to complete this one, but alas, it is done.

Challenger

CodeWars challenge

Write an algorithm that will identify valid IPv4 addresses in dot-decimal format. IPs should be considered valid if they consist of four octets, with values between 0 and 255, inclusive.

Input to the function is guaranteed to be a single string.

Examples Valid inputs:

1.2.3.4
123.45.67.89

Invalid inputs:

1.2.3
1.2.3.4.5
123.456.78.90
123.045.067.089

Note that leading zeros (e.g. 01.02.03.04) are considered invalid.

Thought pattern

I knew what an IP address was, but I didn't know how exactly they worked, but through my studies I figured out about Octets, this is some deeper conversation that I will not get into fully, as that's not the aim of this series of blogs. A IPv4 will have 4 octets separated by periods, this is called dotted decimal notation. I had to delve into some networking resources to learn more about IP addresses, and I encourage you to do the same if you don't know about anything about them.

The minimum value of an octet will be 0, while the maximum will be 255. This means that we will need a conditional statement to check for these values. We also know that IPv4 will have 4 octets, so we need to check for this somehow as well. This is where I started, I ended up having to add more conditional statements to check for other things, but we'll get to that in a moment.

I chose to take the arguments string and split it at the period. Then I want to loop over this array which has strings of numbers within it. I used a for/in loop to iterate over the array. After this, we want to check if the length of the array is 4. We also need to check if a number was passed, we don't want letters. I used the isNaN function, which is a boolean function that returns true if the argument passed is NOT a number, this can be a bit of a confusing point for some, but after time you get used to it.

At this point, I check if the value is over 255 or lower than 0. If any of the aforementioned checks get triggered, we will return false. If it passes our conditions, then we will return true.

function isValidIP(str) {
    //split into an array at the dot
    let strOutput = str.split(".");
    //iterate over the array
    for (let num in strOutput) {
        //is there four sets of numbers? is this even a number at all?
        if (strOutput.length != 4 || isNaN(strOutput[num])) {
            return false;
        //check range of number
        } else if (strOutput[num] > 255 || strOutput[num] < 0) {
            return false;
        } 
    }
    return true;
}

At the end of the challenge description, they say that if the octet leads with a 0 then it is invalid. "01.04.08.16" will fail. In order to check for this, I wanted to check if the length of each string of numbers was more than one character long, if it is more than one char it may not start with a 0.

function isValidIP(str) {

    let strOutput = str.split(".");

    for (let num in strOutput) {

        if (strOutput.length != 4 || isNaN(strOutput[num])) {
            return false;
        } else if (strOutput[num] > 255 || strOutput[num] < 0 || strOutput[num] == "") {
            return false;
        //is this string more than one char? if so, is the first number a zero
        } else if (strOutput[num].toString().length > 1 && strOutput[num][0] == 0) {
            return false;
        }
    }
    return true;
}

At this point I think I'm done, finito, triumphant. So I press the test button and I fail some tests. So, I check out how I failed. One of the test cases passed an argument similar to this "1e2.2e4.4e8.8e8" I thought I already checked if this string contained something that wasn't a number? Well, there are some letters that will pass as numerical values. I then googled why e was a number in JS. It is used to represent exponents. Another test I failed was if the argument passed had a new line character in it, or if there was a space included in the string, and finally if there isn't any characters at all in an octet. Before I split the string, I want to check if there is a white space in the string, if there is an e or if there is a newline character included. After I split the string, when I am checking the range of the number's validity, I also add a condition to check if there is an empty string included.

function isValidIP(str) {
    //check for whitespace, char e, and newline
    if (str.includes(" ") || str.includes("e") || str.includes("\n")) {
        return false;
    }
    let strOutput = str.split(".");

    for (let num in strOutput) {

        if (strOutput.length != 4 || isNaN(strOutput[num])) {
            return false;
       //check for an empty string as well as range
        } else if (strOutput[num] > 255 || strOutput[num] < 0 || strOutput[num] == "") {
            return false;

        } else if (strOutput[num].toString().length > 1 && strOutput[num][0] == 0) {
            return false;
        }
    }
    return true;
}

At this point, I finally passed all the tests. Just like many of the other challenges, looking at other's solutions was very enlightening.

Thanks for reading!