- Notifications
You must be signed in to change notification settings - Fork19
A TypeScript/JavaScript library for working with ASN, IPv4, and IPv6 numbers. It provides representations of these internet protocol numbers with the ability to perform various IP related operations like parsing, validating etc. on them
License
ip-num/ip-num
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
ip-num
is a zero dependency,TypeScript library for working withIPv4
,IPv6
andASN
numbers. It provides representations of these internet protocol numbers with the ability to perform various operations like parsing, validating etc. on them.
ip-num
can be used with both TypeScript and vanila JavaScript. It also support both usage within a browser environment as well as Node.Js environment.
ip-num
's source can be found onGitHub
You can have a play atip-num
's API via the Runkit athttp://bit.ly/ipnum-repl
If you want to useip-num
from within a Node.js environment, you can install it vianpm.
npm install ip-num
check the.travis.yml
file for the versions of Node.jsip-num
is being built and tested with.
If you are using a browser, you would have to use a module bundler likebrowserify,parceljs,webpack etc. to be able to use ip-num as a front-end module.
For quick prototyping, you can download the release from github athttps://github.com/ip-num/ip-num/releases
You can then extract the compressed file and include theip-num.js
file located in thedist
folder.
The functionalityip-num
exposes can be grouped into 2 broad categories:
- Modules representing ASN, IPv4, and IPv6 internet protocol numbers
- Utilities and Validator
How you get access to the above, depends on the module loading mechanism being used. The examples below will show howto accessip-num
using ES module mechanism with TypeScript in Node.js, using CommonJs module mechanism withJavaScript in Node.Js, and by includingip-num
via a script tag with JavaScript in the browser.
Import what you need fromip-num
and use away
import { Asn } from "ip-num/IPNumber";import { IPv4 } from "ip-num/IPNumber";import { IPv6 } from "ip-num/IPNumber";
You can then make use of the imported module in your TypeScript code
let asn = new Asn(65546);asn.toBinaryString() //10000000000001010let ipv4 = new IPv4("74.125.43.99");ipv4.toBinaryString() //01001010011111010010101101100011let ipv6 = new IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");ipv6.toBinaryString() //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
All external modules inip-num
are exported and made available via the globalip-num module. So you canrequire ('ip-num')
and then access the module you want to use in your application, or access the module in one go, whilerequiring; as shown below:
const Asn = require("ip-num").Asn;const IPv4 = require("ip-num").IPv4;const IPv6 = require("ip-num").IPv6;
The imported module can then be used:
let asn = new Asn(65546);asn.toBinaryString() //10000000000001010let ipv4 = new IPv4("74.125.43.99");ipv4.toBinaryString() //01001010011111010010101101100011let ipv6 = new IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");ipv6.toBinaryString() //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Including theip-num
library via the script tag in the browser exposesipnum
variable from which you can accessthe modules exposes by the library.
<script src="https://ip-num.github.io/ip-num/ip-num.js"></script>........let asn = new ipnum.Asn(65546);console.log(asn.toBinaryString()); //10000000000001010let ipv4 = new ipnum.IPv4("74.125.43.99")console.log(ipv4.toBinaryString()); //01001010011111010010101101100011let ipv6 = new ipnum.IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");console.log(ipv6.toBinaryString()); //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Documentation can be found athttps://ip-num.github.io/ip-num/
Find below, some example of the usage ofip-num
. For a more comprehensive overview of the API, please refer to thedocumentation.
An overview covering some part of the module structure ofip-num
is represented below:
IPNumber/ -- module that contains IP numbers implementations├── AbstractIPNum -- contains common implementation to ASN, IPv4 and IPv6 │ ├── Asn│ ├── IPv4| ├── IPv4Mask│ ├── IPv6| ├── IPv6MaskIPRange/ -- module that contains IP ranges implementations├── AbstractIPRange -- contains common implementation for IPv4 and IPv6 CIDR ranges │ ├── IPv4CidrRange│ ├── IPv6CidrRange├── RangedSet -- Represents a continuous segment of either IPv4 or IPv6 numbers without adhering to classless inter-domain routing schemeIPPool/├── Pool -- Represents a collection of IP numbers as single or set
import { Asn } from "ip-num/IPNumber";..........// creatinglet asA = Asn.fromNumber(1234) // using the fromNumber factory method to create an instance from numberlet asB = Asn.fromString("AS1234") // using the fromString factory method to create an instance from stringlet asC = Asn.fromString("1234") // string without the "AS" prefix is also supportedlet asD = Asn.fromString("1.10") // string in asdot+ format is also supportedlet asE = Asn.fromBinaryString('1111') // using the fromBinaryString to create an instance from binary string// converting between different ASN string representationsAsn.fromNumber(65526).toASDotPlus() // will give "0.65526"Asn.fromNumber(65546).toASDot() // will give "1.10"Asn.fromNumber(2).toBinaryString() // will give 10// check if previous and next values exist, getting previous and next valuesAsn.fromNumber(Math.pow(2, 32) - 1).hasNext() // falseAsn.fromNumber(2).hasNext() // trueAsn.fromNumber(0).hasPrevious() // falseAsn.fromNumber(2).hasPrevious() // true
See theASN documentation for more information
import { IPv4 } from "ip-num/IPNumber";// creatinglet firstIPv4 = new IPv4("74.125.43.99") // Creating an instance using the constructorlet secondIPv4 = IPv4.fromNumber(1876843053n) // Using the fromNumber convenience methodlet thirdIPv4 = IPv4.fromDecimalDottedString("111.222.90.45") // Using the fromDecimalDottedString convenience methodlet fourthIPv4 = IPv4.fromBinaryString("01001010011111010010101101100011") // using the fromBinaryString convenience method// converting an IPv4 instance to binary string representationfirstIPv4.toBinaryString() // will be 01001010011111010010101101100011// comparing IPV4firstIPv4.isEquals(thirdIPv4) // falsefirstIPv4.isLessThan(thirdIPv4) // truefirstIPv4.isGreaterThan(thirdIPv4) // false
See theIPv4 documentation for more information
import { IPv6 } from "ip-num/IPNumber";// creatinglet firstIPv6 = new IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") // Creating an instance using the constructorlet secondIPv6 = IPv6.fromNumber(100) // Using the fromNumber convenience methodlet thirdIPv6 = IPv6.fromHexadecimalString("::") // Using the fromDecimalDottedString convenience method. Not abbreviated representation of IPv6 string is supportedlet fourthIPv6 = IPv6.fromBinaryString("01001010011111010010101101100011") // using the fromBinaryString convenience method // converting an IPv6 instance to binary string representationfirstIPv6.toBinaryString() // will be 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 // comparing IPV6firstIPv6.isEquals(thirdIPv6) // falsefirstIPv6.isLessThan(thirdIPv6) // falsefirstIPv6.isGreaterThan(thirdIPv6) // true
See theIPv6 documentation for more information
import {IPv4CidrRange} from "ip-num/IPRange";// creating an IPv4 range from CIDR notationlet ipv4Range = IPv4CidrRange.fromCidr("192.198.0.0/24");// get first and last IPv4 number in the rangeipv4Range.getFirst().toString() // gives 192.198.0.0ipv4Range.getLast().toString() // gives 192.198.0.255// getting number of IPv4 numbers in the rangeipv4Range.getSize() // Returns 256// splitting rangesipv4Range.split()[0].toCidrString() // returns 192.198.0.0/25ipv4Range.split()[1].toCidrString() // returns 192.198.0.128/25
Performing set like operations with IP Ranges:
import {IPv4CidrRange} from "ip-num/IPRange";let containerRange = IPv4CidrRange.fromCidr("192.168.0.0/24");let firstRange = IPv4CidrRange.fromCidr("192.168.0.0/25");let secondRange = IPv4CidrRange.fromCidr("192.168.0.128/25");console.log(containerRange.inside(firstRange)) // falseconsole.log(containerRange.inside(secondRange)) // false;console.log(firstRange.inside(containerRange)); // true;console.log(secondRange.inside(containerRange)); // true;
See theIPv4CidrRange documentation for more information
import {IPv6CidrRange} from "ip-num/IPRange";// creating an IPv6 range from CIDR notationlet ipv6Range = IPv6CidrRange.fromCidr("2001:db8::/33");// get first and last IPv6 number in the rangeipv6Range.getFirst().toString() // gives 2001:db8:0:0:0:0:0:0ipv6Range.getLast().toString() // gives 2001:db8:7fff:ffff:ffff:ffff:ffff:ffff// getting number of IPv6 numbers in the rangeipv6Range.getSize() // Returns 39614081257132168796771975168// splitting rangesipv6Range.split()[0].toCidrString() // returns 2001:db8:0:0:0:0:0:0/34ipv6Range.split()[1].toCidrString() // returns 2001:db8:4000:0:0:0:0:0/34
Performing set like operations with IP Ranges:
import {IPv6CidrRange} from "ip-num/IPRange";let containerRange = new IPv6CidrRange(new IPv6("2001:db8::"), new IPv6Prefix(47));let firstRange = new IPv6CidrRange(new IPv6("2001:db8::"), new IPv6Prefix(48));let secondRange = new IPv6CidrRange(new IPv6("2001:db8:1::"), new IPv6Prefix(48));console.log(containerRange.inside(firstRange)); // falseconsole.log(containerRange.inside(secondRange)); // false;console.log(firstRange.inside(containerRange)) // true;console.log(secondRange.inside(containerRange)) // true;
See theIPv6CidrRange documentation for more information
When working in TypeScript, you have the ability to abstract ASN, IPv4 and IPv6 as an AbstractIPNum, and IPv4CidrRange andIPv6CidrRange as AbstractIPRange
import {AbstractIPNum} from "ip-num/IPNumber";import {AbstractIPRange} from "ip-num/IPRange";import {Asn} from "ip-num/IPNumber";import {IPv4} from "ip-num/IPNumber";import {IPv6} from "ip-num/IPNumber";import {IPv4CidrRange} from "ip-num/IPRange";import {IPv6CidrRange} from "ip-num/IPRange";import {IPv4Prefix} from "ip-num/Prefix";import {IPv6Prefix} from "ip-num/Prefix";// representing ASN, IPv4 and IPv6 as a AbstractIPNumlet ipNumbers: AbstractIPNum[] = [];ipNumbers.push(new Asn("200"));ipNumbers.push(new IPv4("133.245.233.255"));ipNumbers.push(new IPv6("2001:800:0:0:0:0:0:2002"))// console logs AS200// 133.245.233.255// 2001:800:0:0:0:0:0:2002ipNumbers.forEach(ip => { console.log(ip.toString());});// representing IPv4CidrRange and IPv6CidrRange as AbstractIPRangelet ipRanges: AbstractIPRange<IPv4 | IPv6, IPv4Prefix | IPv6Prefix>[] = [];ipRanges.push(IPv4CidrRange.fromCidr("192.198.0.0/24"));ipRanges.push(IPv6CidrRange.fromCidr("2001:db8::/33"));// console logs 192.198.0.0/24// 2001:db8:0:0:0:0:0:0/33ipRanges.forEach(iprange => { console.log(iprange.toCidrString());});
See theIPNumber documentation for more informationSee theIPRange documentation for more information
IPv4Mask and IPv6Mask are used to represent subnet masks in IPv4 and IPv6respectively.
Subnet masks are in all respects IP numbers with the only restriction that they must contain contiguous on bits (1's)followed by contiguous off bits (0's). This means IPv4Mask and IPv6Mask can perform all the operationsavailable on IPv4 and IPv6. The only difference is that the invariant required for a subnet is enforced in theconstructor of IPv4Mask and IPv6Mask. For example:
The following code will throw an exception:
import {IPv4Mask} from 'ip-num/IPNumber'import {IPv6Mask} from 'ip-num/IPNumber'let ipv4Mask = new IPv4Mask("10.255.10.3");let ipv6Mask = new IPv6Mask("3ffe:1900:4545:0003:0200:f8ff:fe21:67cf");
While the following code works fine:
import {IPv4Mask} from 'ip-num/IPNumber'import {IPv6Mask} from 'ip-num/IPNumber'let iPv4Mask = new IPv4Mask("255.0.0.0");let iPv6Mask = new IPv6Mask("ffff:ffff:ffff:ffff:ffff:ffff:0:0");
See theIPv4Mask documentation for more informationSee theIPv6Mask documentation for more information
IPv4-Mapped IPv6 Address IPv6 allows embedding an IPv4 address within an IPv6 address. SeeIPv6 Addresses with Embedded IPv4 Addresses
ip-num
offers various ways to create an IPv4-Mapped IPv6 Address:
import { IPv4 } from "ip-num/IPNumber";let ipv4 = new IPv4("74.125.43.99")ipv4.toIPv4MappedIPv6().toString() // produces ::ffff:4a7d:2b63
import { IPv6 } from "ip-num/IPNumber";import { IPv4 } from "ip-num/IPNumber";let ipv6 = IPv6.fromIPv4(new IPv4("74.125.43.99"))ipv6.toString() // produces ::ffff:4a7d:2b63
import { IPv6 } from "ip-num/IPNumber";let ipv6 = IPv6.fromIPv4DotDecimalString("74.125.43.99")ipv6.toString() // produces ::ffff:4a7d:2b63
Pool
allows for working with collections of IP numbers and ranges.
import {IPv4} from "ip-num/IPNumber";import {Pool} from "ip-num/IPPool";let pool = Pool.fromIPNumbers([IPv4.fromDecimalDottedString("10.0.0.1"), IPv4.fromDecimalDottedString("10.0.0.2")]);let ranges = pool.getRanges();console.log(ranges[0].toCidrRange().toCidrString()); // prints "10.0.0.1/32"console.log(ranges[1].toCidrRange().toCidrString()); // prints "10.0.0.2/32"
import {IPv4} from "ip-num/IPNumber";import {Pool} from "ip-num/IPPool";import {RangedSet} from "ip-num/IPRange";import {IPv4CidrRange} from "ip-num/IPRange";let arrays: RangedSet<IPv4>[] = new Array<RangedSet<IPv4>>();arrays.push(RangedSet.fromCidrRange(IPv4CidrRange.fromCidr("192.168.0.0/26")));arrays.push(RangedSet.fromCidrRange(IPv4CidrRange.fromCidr("192.168.0.64/26")));arrays.push(RangedSet.fromCidrRange(IPv4CidrRange.fromCidr("192.168.0.128/27")));arrays.push(RangedSet.fromCidrRange(IPv4CidrRange.fromCidr("192.168.0.160/27")));arrays.push(RangedSet.fromCidrRange(IPv4CidrRange.fromCidr("192.168.0.192/26")));let pool = Pool.fromRangeSet(arrays);let aggregatedPool = pool.aggregate();console.log(aggregatedPool.getRanges()[0].toRangeString()) // prints("192.168.0.0-192.168.0.255");console.log(aggregatedPool.getRanges().length) // prints 1;
Various validation are exposed via theValidator
module.ip-num
also provide various utility operations. Theseutility operations can be found inBinaryUtils
,IPv6Utils
, andHexadecimalUtils
.
For example to expand and collapse IPv6 numbers:
import * as IPv6Utils from 'ip-num/IPv6Utils'// expandingIPv6Utils.expandIPv6Number("::") // Expands to 0000:0000:0000:0000:0000:0000:0000:0000IPv6Utils.expandIPv6Number("FF01::101")// Expands to FF01:0000:0000:0000:0000:0000:0000:0101// collapsingIPv6Utils.collapseIPv6Number("0000:0000:0000:0000:0000:0000:0000:0000") // Collapses to :: IPv6Utils.collapseIPv6Number("FF01:0:0:0:0:0:0:101") // Collapses to FF01::101
To check if a given string is valid cidr notation:
import {Validator} from 'ip-num/Validator'let result = Validator.isValidIPv4CidrNotation("123.234.334.23")// result => [false, ["Cidr notation should be in the form [ip number]/[range]"]]let result = Validator.isValidIPv4CidrNotation("10.0.0.0/8")// result => [true, []]
See theValidator documentation for more informationSee theBinaryUtils documentation for more informationSee theIPv6Utils documentation for more informationSee theHexadecimalUtils documentation for more information
Theip-num
library is released under the MIT license
To discuss a new feature or ask a question, open an issue. Find the issue trackerhere
Found a bug and you want to provide a fix for it? Then feel free to submit a pull request. It will be appreciated if the changes made are backed with tests.
View latest releaseshere
- Fixes a cyclic dependency bug.Issue #24
- Introduced AbstractIpRange to abstract over the IPRange (ie: IPv4Range and IPv6Range).Issue #15
- Extend the IPRange interface.Issue #20
- Add method to IPRange to return the adjacent ranges.Issue #19
- Add ability to validate if a CIDR notation represents a valid range.Issue #21
- Changed target to es5 so as to support Internet Explorer 11.Issue #22
- Fixed isValidIPv4String() incorrectly returns true for some invalid addresses.Issue #9
- Improved Validator.isValidIPv6String and added test coverage.Issue #10
- Added convenient methods for creating IPv4 (
IPv4.fromBinaryString
) and IPv6 (IPv6.fromBinaryString
) from binary stringIssue #11 - Added convenient methods for creating ASN (
ASN.fromBinaryString
)Issue #13 - Prepend with "::" if toString value for IPv6 has leading zeros.Issue #12
- Implemented support for IPv4-Mapped IPv6 Address.Issue #3
Version 1.1.0 was Unpublished.
- Renamed Subnet to SubnetMaskIssue #1
- Fixed the throwing ofinvalid integer: NaN when invalid IPv4 and IPv6 strings are passed to Validator.isValidIPv4String and Validator.isValidIPv6String validators. Fixed bysaiyeekIssue #5
- Fixed
Validator.isValidIPv4CidrNotation
improper validation of IPv4 CIDRIssue #6
Special thanks to JetBrains for supporting the development ofip-num
with a free IDE licence.
You can find more information about JetBrains support for open source projectshere
About
A TypeScript/JavaScript library for working with ASN, IPv4, and IPv6 numbers. It provides representations of these internet protocol numbers with the ability to perform various IP related operations like parsing, validating etc. on them
Topics
Resources
License
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Contributors7
Uh oh!
There was an error while loading.Please reload this page.