| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | export function generateRandomIPv6(ipv6Block: string): string { |
| | |
| | const [baseAddress, blockSize] = ipv6Block.split("/"); |
| | const blockBits = parseInt(blockSize, 10); |
| |
|
| | if (isNaN(blockBits) || blockBits < 1 || blockBits > 128) { |
| | throw new Error("Invalid IPv6 block size"); |
| | } |
| |
|
| | |
| | const expandedBase = expandIPv6(baseAddress); |
| |
|
| | |
| | const baseBytes = ipv6ToBytes(expandedBase); |
| |
|
| | |
| | for (let i = Math.floor(blockBits / 8); i < 16; i++) { |
| | const bitOffset = Math.max(0, blockBits - i * 8); |
| | if (bitOffset === 0) { |
| | |
| | baseBytes[i] = Math.floor(Math.random() * 256); |
| | } else if (bitOffset < 8) { |
| | |
| | const mask = (1 << (8 - bitOffset)) - 1; |
| | const randomPart = Math.floor(Math.random() * (mask + 1)); |
| | baseBytes[i] = (baseBytes[i] & ~mask) | randomPart; |
| | } |
| | |
| | } |
| |
|
| | |
| | return bytesToIPv6(baseBytes); |
| | } |
| |
|
| | |
| | |
| | |
| | function expandIPv6(address: string): string { |
| | |
| | if (address.includes("::")) { |
| | const parts = address.split("::"); |
| | const leftParts = parts[0] ? parts[0].split(":") : []; |
| | const rightParts = parts[1] ? parts[1].split(":") : []; |
| | const missingParts = 8 - leftParts.length - rightParts.length; |
| | const middle = Array(missingParts).fill("0000"); |
| | const allParts = [...leftParts, ...middle, ...rightParts]; |
| | return allParts.map((p) => p.padStart(4, "0")).join(":"); |
| | } |
| |
|
| | |
| | return address.split(":").map((p) => p.padStart(4, "0")).join(":"); |
| | } |
| |
|
| | |
| | |
| | |
| | function ipv6ToBytes(address: string): number[] { |
| | const parts = address.split(":"); |
| | const bytes: number[] = []; |
| |
|
| | for (const part of parts) { |
| | const value = parseInt(part, 16); |
| | bytes.push((value >> 8) & 0xFF); |
| | bytes.push(value & 0xFF); |
| | } |
| |
|
| | return bytes; |
| | } |
| |
|
| | |
| | |
| | |
| | function bytesToIPv6(bytes: number[]): string { |
| | const parts: string[] = []; |
| |
|
| | for (let i = 0; i < 16; i += 2) { |
| | const value = (bytes[i] << 8) | bytes[i + 1]; |
| | parts.push(value.toString(16)); |
| | } |
| |
|
| | |
| | let ipv6 = parts.join(":"); |
| |
|
| | |
| | const zeroSequences = ipv6.match(/(^|:)(0:)+/g); |
| | if (zeroSequences) { |
| | const longestZeroSeq = zeroSequences.reduce((a, b) => |
| | a.length > b.length ? a : b |
| | ); |
| | ipv6 = ipv6.replace(longestZeroSeq, longestZeroSeq[0] + ":"); |
| | } |
| |
|
| | return ipv6; |
| | } |
| |
|