multiaddr
Version:
multiaddr implementation (binary + string representation of network addresses)
105 lines (88 loc) • 2.73 kB
JavaScript
const isIp = require('is-ip')
const { toString: uint8ArrayToString } = require('uint8arrays/to-string')
const isIP = isIp
const isV4 = isIp.v4
const isV6 = isIp.v6
// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L7
// @ts-ignore - this is copied from the link above better to keep it the same
const toBytes = function (ip, buff, offset) {
offset = ~~offset
let result
if (isV4(ip)) {
result = buff || new Uint8Array(offset + 4)
// @ts-ignore
// eslint-disable-next-line array-callback-return
ip.split(/\./g).map(function (byte) {
result[offset++] = parseInt(byte, 10) & 0xff
})
} else if (isV6(ip)) {
const sections = ip.split(':', 8)
let i
for (i = 0; i < sections.length; i++) {
const isv4 = isV4(sections[i])
let v4Buffer
if (isv4) {
v4Buffer = toBytes(sections[i])
sections[i] = uint8ArrayToString(v4Buffer.slice(0, 2), 'base16')
}
if (v4Buffer && ++i < 8) {
sections.splice(i, 0, uint8ArrayToString(v4Buffer.slice(2, 4), 'base16'))
}
}
if (sections[0] === '') {
while (sections.length < 8) sections.unshift('0')
} else if (sections[sections.length - 1] === '') {
while (sections.length < 8) sections.push('0')
} else if (sections.length < 8) {
for (i = 0; i < sections.length && sections[i] !== ''; i++);
const argv = [i, '1']
for (i = 9 - sections.length; i > 0; i--) {
argv.push('0')
}
sections.splice.apply(sections, argv)
}
result = buff || new Uint8Array(offset + 16)
for (i = 0; i < sections.length; i++) {
const word = parseInt(sections[i], 16)
result[offset++] = (word >> 8) & 0xff
result[offset++] = word & 0xff
}
}
if (!result) {
throw Error('Invalid ip address: ' + ip)
}
return result
}
// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L63
// @ts-ignore - this is copied from the link above better to keep it the same
const toString = function (buff, offset, length) {
offset = ~~offset
length = length || (buff.length - offset)
const result = []
let string
const view = new DataView(buff.buffer)
if (length === 4) {
// IPv4
for (let i = 0; i < length; i++) {
result.push(buff[offset + i])
}
string = result.join('.')
} else if (length === 16) {
// IPv6
for (let i = 0; i < length; i += 2) {
result.push(view.getUint16(offset + i).toString(16))
}
string = result.join(':')
string = string.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3')
string = string.replace(/:{3,4}/, '::')
}
return string
}
module.exports = {
isIP,
isV4,
isV6,
toBytes,
toString
}