IPv6 Subnet Calculator
Results will appear here.
// Helper function to expand IPv6 address to its full 8-hextet form
function expandIPv6(ipv6) {
var parts = ipv6.split('::');
var expanded = ";
if (parts.length === 1) {
// No '::' found, just pad each part
expanded = parts[0].split(':').map(function(p) { return p.padStart(4, '0'); }).join(':');
} else if (parts.length === 2) {
// '::' found, handle compression
var firstPart = parts[0].split(':').filter(function(p) { return p !== "; });
var lastPart = parts[1].split(':').filter(function(p) { return p !== "; });
var missingParts = 8 – (firstPart.length + lastPart.length);
var middle = Array(missingParts).fill('0000').join(':');
var firstExpanded = firstPart.map(function(p) { return p.padStart(4, '0'); }).join(':');
var lastExpanded = lastPart.map(function(p) { return p.padStart(4, '0'); }).join(':');
if (firstPart.length > 0 && lastPart.length > 0) {
expanded = firstExpanded + ':' + middle + ':' + lastExpanded;
} else if (firstPart.length > 0) { // e.g., '1::'
expanded = firstExpanded + ':' + middle;
} else if (lastPart.length > 0) { // e.g., '::1'
expanded = middle + ':' + lastExpanded;
} else { // e.g., '::'
expanded = middle; // All zeros
}
} else {
throw new Error("Invalid IPv6 address: multiple '::' found.");
}
return expanded;
}
// Helper function to convert an expanded IPv6 address string to a BigInt
function ipv6ToBigInt(expandedIPv6) {
var hextets = expandedIPv6.split(':');
var bigInt = 0n;
for (var i = 0; i < hextets.length; i++) {
bigInt = (bigInt << 16n) | BigInt(parseInt(hextets[i], 16));
}
return bigInt;
}
// Helper function to convert a BigInt back to a canonical IPv6 string
function bigIntToIPv6(bigInt) {
var hextets = [];
for (var varI = 0; varI >= 16n;
}
// Canonicalize each hextet (remove leading zeros, but keep '0' for '0000')
var canonicalHextets = hextets.map(function(h) {
return h === '0' ? '0' : parseInt(h, 16).toString(16);
});
// Find the longest sequence of zero hextets for '::' compression
var bestStart = -1;
var bestLength = 0;
var currentStart = -1;
var currentLength = 0;
for (var varI = 0; varI bestLength) {
bestLength = currentLength;
bestStart = currentStart;
}
currentStart = -1;
currentLength = 0;
}
}
// Check for trailing zeros after the loop
if (currentLength > bestLength) {
bestLength = currentLength;
bestStart = currentStart;
}
// Apply '::' compression if a sequence of at least two zero hextets is found
if (bestLength >= 2) {
var result = [];
for (var varI = 0; varI < canonicalHextets.length; varI++) {
if (varI === bestStart) {
result.push(''); // Placeholder for '::'
varI += bestLength – 1; // Skip the compressed zeros
} else {
result.push(canonicalHextets[varI]);
}
}
return result.join(':'); // This correctly handles '::' at start/end/middle
} else {
return canonicalHextets.join(':');
}
}
// Helper function for basic IPv6 format validation
function isValidIPv6(ipv6) {
var ipv6Regex = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^((?:[0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4})*)?)::((?:[0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4})*)?)$/i;
return ipv6Regex.test(ipv6);
}
function calculateIPv6Subnet() {
var ipv6AddressInput = document.getElementById('ipv6Address').value.trim();
var prefixLengthInput = document.getElementById('prefixLength').value.trim();
var resultDiv = document.getElementById('ipv6SubnetResult');
resultDiv.innerHTML = ''; // Clear previous results
if (!ipv6AddressInput || !prefixLengthInput) {
resultDiv.innerHTML = 'Please enter both IPv6 Address and Prefix Length.';
return;
}
// Remove any existing prefix length from the address if present
var addressParts = ipv6AddressInput.split('/');
var rawIPv6Address = addressParts[0];
if (!isValidIPv6(rawIPv6Address)) {
resultDiv.innerHTML = 'Invalid IPv6 address format. Please ensure it follows standard IPv6 notation (e.g., 2001:db8::1 or fe80::1).';
return;
}
var prefixLength = parseInt(prefixLengthInput, 10);
if (isNaN(prefixLength) || prefixLength 128) {
resultDiv.innerHTML = 'Prefix Length must be a number between 0 and 128.';
return;
}
try {
var expandedIPv6 = expandIPv6(rawIPv6Address);
var addressBigInt = ipv6ToBigInt(expandedIPv6);
// Calculate the network mask: (2^prefixLength – 1) shifted left
var networkMaskBigInt = ((1n << BigInt(prefixLength)) – 1n) << (128n – BigInt(prefixLength));
// Apply the mask to get the network address (zeros out host bits)
var networkAddressBigInt = addressBigInt & networkMaskBigInt;
// Calculate the total number of addresses in the subnet (2^(128 – prefixLength))
var numberOfAddressesBigInt = 1n << (128n – BigInt(prefixLength));
// In IPv6, the network address is typically considered the first usable address
var firstHostAddressBigInt = networkAddressBigInt;
// The last host address is the network address plus (total addresses – 1)
var lastHostAddressBigInt = networkAddressBigInt + numberOfAddressesBigInt – 1n;
// The next subnet's network address is the current network address plus total addresses
var nextSubnetAddressBigInt = networkAddressBigInt + numberOfAddressesBigInt;
// Convert BigInt results back to canonical IPv6 string format
var networkAddress = bigIntToIPv6(networkAddressBigInt);
var firstHostAddress = bigIntToIPv6(firstHostAddressBigInt);
var lastHostAddress = bigIntToIPv6(lastHostAddressBigInt);
var nextSubnetAddress = bigIntToIPv6(nextSubnetAddressBigInt);
resultDiv.innerHTML = `
Network Address: ${networkAddress}/${prefixLength}
Prefix Length: ${prefixLength}
Number of Addresses: ${numberOfAddressesBigInt.toLocaleString('en-US')}
First Host Address: ${firstHostAddress}
Last Host Address: ${lastHostAddress}
Next Subnet Address: ${nextSubnetAddress}/${prefixLength}
`;
} catch (e) {
resultDiv.innerHTML = 'An error occurred during calculation: ' + e.message + ";
console.error(e);
}
}
Understanding IPv6 Subnetting
IPv6 (Internet Protocol version 6) is the latest version of the Internet Protocol, designed to replace IPv4. Its primary advantage is its vastly larger address space, using 128-bit addresses compared to IPv4's 32-bit addresses. This enormous address pool (approximately 3.4 x 10^38 unique addresses) eliminates the need for Network Address Translation (NAT) and provides ample room for future growth of the internet.
Why Subnet IPv6?
Despite the massive address space, subnetting is still crucial in IPv6 for several reasons:
- Hierarchical Addressing: Subnetting allows for a logical and hierarchical organization of networks, making routing more efficient and manageable.
- Network Segmentation: It helps in segmenting large networks into smaller, more manageable parts, improving security, performance, and troubleshooting.
- Delegation: ISPs and organizations can delegate smaller blocks of addresses to customers or departments, maintaining a structured address plan.
- Security: Isolating different network segments can limit the scope of security breaches.
Key Differences from IPv4 Subnetting
While the core concept of dividing a network into smaller subnets remains, IPv6 subnetting has some notable differences:
- Address Length: IPv6 addresses are 128 bits long, compared to IPv4's 32 bits.
- No Broadcast Address: IPv6 does not use broadcast addresses. Instead, it uses multicast for one-to-many communication and anycast for one-to-nearest communication.
- Number of Hosts: The number of addresses in an IPv6 subnet is astronomically large. A typical /64 subnet, commonly used for individual links, contains 2^64 addresses. This means there's no practical concern about running out of host addresses within a subnet.
- Common Prefix Lengths:
- /128: A single host address.
- /64: The standard prefix length for a single link or subnet. It provides enough addresses for Stateless Address Autoconfiguration (SLAAC) and future expansion.
- /48: Often assigned to an end-site (e.g., a company or large organization) by an ISP, allowing for 2^16 (65,536) /64 subnets within that site.
- /56: A smaller block for residential or small business customers, allowing for 2^8 (256) /64 subnets.
- Interface ID: The last 64 bits of an IPv6 address typically form the Interface ID, which uniquely identifies an interface on a link.
How the Calculator Works
This IPv6 Subnet Calculator takes an IPv6 address and a prefix length as input. It then performs the following calculations:
- Parses the IPv6 Address: It expands any shorthand notation (like
::) to the full 128-bit representation.
- Converts to BigInt: The 128-bit address is converted into a JavaScript BigInt for precise mathematical operations.
- Calculates Network Address: It applies the given prefix length to determine the network portion of the address, effectively zeroing out the host bits.
- Determines Number of Addresses: Calculates 2^(128 – prefix length) to find the total number of addresses within that subnet.
- Identifies First and Last Host Addresses: For IPv6, the network address itself is typically considered the first usable address. The last host address is the highest address in the subnet range.
- Calculates Next Subnet Address: This helps in planning contiguous address blocks.
Example Usage:
Let's say you have been assigned the IPv6 block 2001:db8:abcd::/48 and you want to create a /64 subnet for a specific LAN segment.
Input:
- IPv6 Address:
2001:db8:abcd:1:: (an address within your /48 block)
- Prefix Length:
64
Output (example):
- Network Address:
2001:db8:abcd:1::/64
- Prefix Length:
64
- Number of Addresses: 18,446,744,073,709,551,616 (2^64)
- First Host Address:
2001:db8:abcd:1::
- Last Host Address:
2001:db8:abcd:1:ffff:ffff:ffff:ffff
- Next Subnet Address:
2001:db8:abcd:2::/64
This calculator helps network administrators and engineers efficiently plan and manage their IPv6 address space.