PHP's inet_pton in TypeScript

✓ Verified: PHP 8.3
Examples tested against actual runtime. CI re-verifies continuously. Only documented examples are tested.

How to use

Install via yarn add locutus and import: import { inet_pton } from 'locutus/php/network/inet_pton'.

Or with CommonJS: const { inet_pton } = require('locutus/php/network/inet_pton')

Use a bundler that supports tree-shaking so you only ship the functions you actually use. Vite, webpack, Rollup, and Parcel all handle this. For server-side use this is less of a concern.

Examples

These examples are extracted from test cases that automatically verify our functions against their native counterparts.

#codeexpected result
1inet_pton('::')'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'
2inet_pton('127.0.0.1')'\x7F\x00\x00\x01'

Here's what our current TypeScript equivalent to PHP's inet_pton looks like.

export function inet_pton(a: string): string | false {
// 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: string[] = []
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))
}

Improve this function

Locutus is a community effort following The McDonald's Theory: we ship first iterations, hoping others will improve them. If you see something that could be better, we'd love your contribution.

View on GitHub · Edit on GitHub · View Raw


« More PHP network functions


Star