0

I am trying to develop an IPv6 subnetting calculator and I need to display the address in its expanded format. That is, suppose we have this IP address: 2001:DB8:C003:1::F00D/48, I need to replace the :: with zeros such as :0000:0000:0000: according to the number of fields already present(max 8 fields).
I did this with a switch statement but an IPv6 address in its condensed notation is to omit leading zeros as well. From the above IP address, :DB8 is condensed. It is actually :0DB8 and I need to accommodate for it as well.

This is what I've tried so far:

Codes

 /*To calculate hex field*/
var field = (ip.split(":").length - 1);

var condens = ":0000:0000:0000:0000:0000:0000:0000";

switch(field)
{
    case 1:
    {
        var block=ip.substring(ip.lastIndexOf(":")+1,ip.lastIndexOf(":")); //to extract strings between the special character
        var inputString = ip,
                expand = inputString.replace(/(::)+/g, condens);
        console.log(expand);
        while(block.length < 4)
        {
            //replace fields only with missing characters with 0
        }
        $("#expand").attr("value",expand);
        break;
    }
    case 2:
    {
        var inputString = ip,
                expand = inputString.replace(/(::)+/g, ":0000:0000:0000:0000:0000:0000:0000");
        console.log(expand);
        $("#expand").attr("value",expand);
        break;
    }
    case 3:
    {
        var inputString = ip,
                expand = inputString.replace(/(::)+/g, ":0000:0000:0000:0000:0000:");
        console.log(expand);
        $("#expand").attr("value",expand);
        break;
    }
    case 4:
    {
        var inputString = ip,
                expand = inputString.replace(/(::)+/g, ":0000:0000:0000:0000:");
        console.log(expand);
        $("#expand").attr("value",expand);
        break;
    }
    case 5:
    {
        var inputString = ip,
                expand = inputString.replace(/(::)+/g, ":0000:0000:0000:");
        console.log(expand);
        $("#expand").attr("value",expand);
        break;
    }
    case 6:
    {
        var inputString = ip,
                expand = inputString.replace(/(::)+/g, ":0000:0000:");
        console.log(expand);
        $("#expand").attr("value",expand);
        break;
    }
}


As you can see, currently I'm extracting substrings between :. I need to extract substring only with length < 4 and add the leading zeros to make the length upto 4. Then, replace the substring I extracted with the new one(with the leading zeros and print it.

Can someone help me please? Thanks.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Manisha Singh Sanoo
  • 919
  • 1
  • 13
  • 42

1 Answers1

2

It can be done in a much simpler way:

var input = '2001:DB8:C003:1::F00D/48';

var tmp = input.split(/\//);
var ip = tmp[0];
var subnet = tmp[1];

// if the ip is compacted
if (ip.match('::')) {
    // + 1 back because there is an extra empty element in the array (because of ::)
    var missingPartsNumber = 8 - ip.split(':').length + 1;

    // replace the :: by the number of : needed to have 8 parts in the ip
    ip = ip.replace(/::/, pad('', missingPartsNumber + 1, ':'));
}

var paddedIp = ip.split(':').map(function (part) {
    return pad(part, 4, '0')
}).join(':') + '/' + subnet; // add the subnet back if needed

// from http://stackoverflow.com/a/10073788/5388620
function pad(n, width, z) {
    z = z || '0';
    n = n + '';
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

snippet.log('in : ' + input);
snippet.log('out: ' + paddedIp);
<script src="https://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Update

Updated my code to actually return a valid IPV6, I used explicit variable names so it's easy to read.

Shanoor
  • 13,344
  • 2
  • 29
  • 40