UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

75 lines (74 loc) 2.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.inet_pton = inet_pton; function inet_pton(a) { // discuss at: https://locutus.io/php/inet_pton/ // parity verified: PHP 8.3 // original by: Theriault (https://github.com/Theriault) // improved by: alromh87 and JamieSlome // example 1: inet_pton('::') // returns 1: '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' // example 2: inet_pton('127.0.0.1') // returns 2: '\x7F\x00\x00\x01' const f = String.fromCharCode; // IPv4 const ipv4Match = a.match(/^(?:\d{1,3}(?:\.|$)){4}/); if (ipv4Match) { const octets = ipv4Match[0] .split('.') .slice(0, 4) .map((part) => Number.parseInt(part, 10)); const [a0, a1, a2, a3] = octets; if (a0 === undefined || a1 === undefined || a2 === undefined || a3 === undefined || octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) { return false; } const packed = f(a0, a1, a2, a3); // Return if 4 bytes, otherwise false. return packed.length === 4 ? packed : false; } // IPv6 if (a.length > 39) { return false; } const segments = a.split('::'); if (segments.length > 2) { return false; } // :: can't be used more than once in IPv6. const reHexDigits = /^[\da-f]{1,4}$/i; const packedSegments = []; for (const segment of segments) { if (segment.length === 0) { packedSegments.push(''); continue; } const hextets = segment.split(':'); let packed = ''; for (const hextetSource of hextets) { const hextet = hextetSource; // check if valid hex string up to 4 chars if (!reHexDigits.test(hextet)) { return false; } const parsedHextet = parseInt(hextet, 16); // Would be NaN if it was blank, return false. if (Number.isNaN(parsedHextet)) { // Invalid IP. return false; } packed += f(parsedHextet >> 8, parsedHextet & 0xff); } packedSegments.push(packed); } const bytesLength = packedSegments.reduce((total, part) => total + part.length, 0); if (bytesLength > 16) { return false; } if (segments.length === 1 && bytesLength !== 16) { return false; } return packedSegments.join('\x00'.repeat(16 - bytesLength)); }