Skip to content

Commit

Permalink
feat: add parseCDIR function
Browse files Browse the repository at this point in the history
  • Loading branch information
Arcath committed Jul 26, 2022
1 parent a56a424 commit 3bc871c
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/functions/network.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {parseCDIR} from '../index'

describe('Network', () => {
it('should parse', () => {
const ip = parseCDIR('10.20.30.40/24')

expect(ip.ip).toBe('10.20.30.40')
expect(ip.bitmask).toBe('24')
expect(ip.binary).toBe('00001010000101000001111000101000')
expect(ip.binaryMask).toBe('11111111111111111111111100000000')
expect(ip.binaryNetwork).toBe('00001010000101000001111000000000')
expect(ip.network).toBe('10.20.30.0')
expect(ip.mask).toBe('255.255.255.0')
expect(ip.binaryBroadcast).toBe('00001010000101000001111011111111')
expect(ip.broadcast).toBe('10.20.30.255')
expect(ip.first).toBe('10.20.30.1')
expect(ip.last).toBe('10.20.30.254')
expect(ip.size).toBe(254)

const smallNetwork = parseCDIR('192.168.1.30/29')

expect(smallNetwork.mask).toBe('255.255.255.248')
expect(smallNetwork.network).toBe('192.168.1.24')
expect(smallNetwork.broadcast).toBe('192.168.1.31')
expect(smallNetwork.size).toBe(6)
})
})
106 changes: 106 additions & 0 deletions src/functions/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
const binaryToIp = (binaryIp: string) => {
const blocks = [
binaryIp.substring(0, 8),
binaryIp.substring(8, 16),
binaryIp.substring(16, 24),
binaryIp.substring(24, 32)
]

return blocks
.map(block => {
return parseInt(block, 2)
})
.join('.')
}

interface CIDRObject {
/** The IP as a binary string */
binary: string
/** The broadcast address of the network as a binary string */
binaryBroadcast: string
/** The network mask as a binary string */
binaryMask: string
/** The network assdress as a binary string */
binaryNetwork: string
/** The CDIR bitmask */
bitmask: string
/** The boardcast address as an IP */
broadcast: string
/** The first IP in the network */
first: string
/** The ip */
ip: string
/** The last IP in the network */
last: string
/** The netmask as an IP */
mask: string
/** The network IP */
network: string
/** The number of usable hosts in the network */
size: number
}

/**
* Parse an IP in CDIR notation
*
* @param cdir An IP in CDIR notation e.g. 10.20.30.40/24
* @returns An instance of `CDIRObject`
*/
export const parseCDIR = (cdir: string): CIDRObject => {
const [ip, bitmask] = cdir.split('/')

const binary = ip
.split('.')
.map(block => {
return parseInt(block, 10).toString(2).padStart(8, '0')
})
.join('')

const binaryMask = ''.padStart(parseInt(bitmask, 10), '1').padEnd(32, '0')

const binaryNetwork = binary
.split('')
.map((bit, i) => {
if (binaryMask[i] === '1') {
return bit
}

return '0'
})
.join('')

const binaryBroadcast = binary
.split('')
.map((bit, i) => {
if (binaryMask[i] === '1') {
return bit
}

return '1'
})
.join('')

const broadcast = binaryToIp(binaryBroadcast)
const network = binaryToIp(binaryNetwork)
const mask = binaryToIp(binaryMask)

const first = binaryToIp(binaryNetwork.replace(/0$/, '1'))
const last = binaryToIp(binaryBroadcast.replace(/1$/, '0'))

const size = parseInt(binaryBroadcast, 2) - parseInt(binaryNetwork, 2) - 1

return {
binary,
binaryBroadcast,
binaryMask,
binaryNetwork,
bitmask,
broadcast,
first,
ip,
last,
mask,
network,
size
}
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export {
} from './functions/increment'
export {indexedBy, IndexedArray, IndexedByOptions} from './functions/indexed-by'
export {keys} from './functions/keys'
export {parseCDIR} from './functions/network'
export {mapProperty} from './functions/map-property'
export {rangeAsString, rangeAsArray} from './functions/range-as-string'
export {
Expand Down

0 comments on commit 3bc871c

Please sign in to comment.