Giter Site home page Giter Site logo

ip-num / ip-num Goto Github PK

View Code? Open in Web Editor NEW
163.0 5.0 17.0 2.91 MB

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

Home Page: https://ip-num.github.io/ip-num/

License: MIT License

TypeScript 99.70% JavaScript 0.30%
ip-address ipv4 ipv6 asn cidr

ip-num's Introduction

Coverage Status

ip-num

ip-num is a zero dependency, TypeScript library for working with IPv4, IPv6 and ASN 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 on GitHub

You can have a play at ip-num's API via the Runkit at http://bit.ly/ipnum-repl

Installation

Node.js

If you want to use ip-num from within a Node.js environment, you can install it via npm.

npm install ip-num

check the .travis.yml file for the versions of Node.js ip-num is being built and tested with.

Browser

If you are using a browser, you would have to use a module bundler like browserify, 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 at https://github.com/ip-num/ip-num/releases

You can then extract the compressed file and include the ip-num.js file located in the dist folder.

Usage

The functionality ip-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 how to access ip-num using ES module mechanism with TypeScript in Node.js, using CommonJs module mechanism with JavaScript in Node.Js, and by including ip-num via a script tag with JavaScript in the browser.

ES module with TypeScript

Import what you need from ip-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() //10000000000001010

let ipv4 = new IPv4("74.125.43.99");
ipv4.toBinaryString() //01001010011111010010101101100011

let ipv6 = new IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
ipv6.toBinaryString() //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

CommonJs with JavaScript

All external modules in ip-num are exported and made available via the global ip-num module. So you can require ('ip-num') and then access the module you want to use in your application, or access the module in one go, while requiring; 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() //10000000000001010

let ipv4 = new IPv4("74.125.43.99");
ipv4.toBinaryString() //01001010011111010010101101100011

let ipv6 = new IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
ipv6.toBinaryString() //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

Via Script tag with JavaScript

Including the ip-num library via the script tag in the browser exposes ipnum variable from which you can access the 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()); //10000000000001010

let ipv4 = new ipnum.IPv4("74.125.43.99")
console.log(ipv4.toBinaryString()); //01001010011111010010101101100011

let ipv6 = new ipnum.IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
console.log(ipv6.toBinaryString()); //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

Documentation

Documentation can be found at https://ip-num.github.io/ip-num/

Examples

Find below, some example of the usage of ip-num. For a more comprehensive overview of the API, please refer to the documentation.

Overview

An overview covering some part of the module structure of ip-num is represented below:

IPNumber/ -- module that contains IP numbers implementations
├── AbstractIPNum -- contains common implementation to ASN, IPv4 and IPv6 
│   ├── Asn
│   ├── IPv4
|     ├── IPv4Mask
│   ├── IPv6
|     ├── IPv6Mask

IPRange/ -- 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 scheme

IPPool/
├── Pool -- Represents a collection of IP numbers as single or set

ASN

import { Asn } from "ip-num/IPNumber";
..........
// creating
let asA = Asn.fromNumber(1234) // using the fromNumber factory method to create an instance from number
let asB = Asn.fromString("AS1234") // using the fromString factory method to create an instance from string
let asC = Asn.fromString("1234") // string without the "AS" prefix is also supported
let asD = Asn.fromString("1.10") // string in asdot+ format is also supported
let asE = Asn.fromBinaryString('1111') // using the fromBinaryString to create an instance from binary string

// converting between different ASN string representations
Asn.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 values
Asn.fromNumber(Math.pow(2, 32) - 1).hasNext() // false
Asn.fromNumber(2).hasNext() // true
Asn.fromNumber(0).hasPrevious() // false
Asn.fromNumber(2).hasPrevious() // true

See the ASN documentation for more information

IPv4

import { IPv4 } from "ip-num/IPNumber";

// creating
let firstIPv4 = new IPv4("74.125.43.99") // Creating an instance using the constructor
let secondIPv4 = IPv4.fromNumber(1876843053n) // Using the fromNumber convenience method
let thirdIPv4 = IPv4.fromDecimalDottedString("111.222.90.45") // Using the fromDecimalDottedString convenience method
let fourthIPv4 = IPv4.fromBinaryString("01001010011111010010101101100011") // using the fromBinaryString convenience method

// converting an IPv4 instance to binary string representation
firstIPv4.toBinaryString() // will be 01001010011111010010101101100011

// comparing IPV4
firstIPv4.isEquals(thirdIPv4) // false
firstIPv4.isLessThan(thirdIPv4) // true
firstIPv4.isGreaterThan(thirdIPv4) // false

See the IPv4 documentation for more information

IPv6

import { IPv6 } from "ip-num/IPNumber";

// creating
let firstIPv6 = new IPv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") // Creating an instance using the constructor
let secondIPv6 = IPv6.fromNumber(100) // Using the fromNumber convenience method
let thirdIPv6 = IPv6.fromHexadecimalString("::") // Using the fromDecimalDottedString convenience method. Not abbreviated representation of IPv6 string is supported
let fourthIPv6 = IPv6.fromBinaryString("01001010011111010010101101100011") // using the fromBinaryString convenience method
   
// converting an IPv6 instance to binary string representation
firstIPv6.toBinaryString() // will be 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
   
// comparing IPV6
firstIPv6.isEquals(thirdIPv6) // false
firstIPv6.isLessThan(thirdIPv6) // false
firstIPv6.isGreaterThan(thirdIPv6) // true

See the IPv6 documentation for more information

IPv4 Ranges

import {IPv4CidrRange} from "ip-num/IPRange";

// creating an IPv4 range from CIDR notation
let ipv4Range = IPv4CidrRange.fromCidr("192.198.0.0/24");

// get first and last IPv4 number in the range
ipv4Range.getFirst().toString() // gives 192.198.0.0
ipv4Range.getLast().toString() // gives 192.198.0.255

// getting number of IPv4 numbers in the range
ipv4Range.getSize() // Returns 256

// splitting ranges
ipv4Range.split()[0].toCidrString() // returns 192.198.0.0/25
ipv4Range.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)) // false

console.log(containerRange.inside(secondRange)) // false;

console.log(firstRange.inside(containerRange)); // true;
console.log(secondRange.inside(containerRange)); // true;

See the IPv4CidrRange documentation for more information

IPv6 Ranges

import {IPv6CidrRange} from "ip-num/IPRange";

// creating an IPv6 range from CIDR notation
let ipv6Range = IPv6CidrRange.fromCidr("2001:db8::/33");

// get first and last IPv6 number in the range
ipv6Range.getFirst().toString() // gives 2001:db8:0:0:0:0:0:0
ipv6Range.getLast().toString() // gives 2001:db8:7fff:ffff:ffff:ffff:ffff:ffff

// getting number of IPv6 numbers in the range
ipv6Range.getSize() // Returns 39614081257132168796771975168

// splitting ranges
ipv6Range.split()[0].toCidrString() // returns 2001:db8:0:0:0:0:0:0/34
ipv6Range.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)); // false
console.log(containerRange.inside(secondRange)); // false;

console.log(firstRange.inside(containerRange)) // true;
console.log(secondRange.inside(containerRange)) // true;

See the IPv6CidrRange documentation for more information

AbstractIPNum and AbstractIPRange

When working in TypeScript, you have the ability to abstract ASN, IPv4 and IPv6 as an AbstractIPNum, and IPv4CidrRange and IPv6CidrRange 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 AbstractIPNum
let 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:2002
ipNumbers.forEach(ip => {
   console.log(ip.toString());
});


// representing IPv4CidrRange and IPv6CidrRange as AbstractIPRange

let 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/33
ipRanges.forEach(iprange => {
   console.log(iprange.toCidrString());
});

See the IPNumber documentation for more information See the IPRange documentation for more information

IPv4Mask and IPv6Mask

IPv4Mask and IPv6Mask are used to represent subnet masks in IPv4 and IPv6 respectively.

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 operations available on IPv4 and IPv6. The only difference is that the invariant required for a subnet is enforced in the constructor 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 the IPv4Mask documentation for more information See the IPv6Mask documentation for more information

IPv4-Mapped IPv6 Address Support

IPv4-Mapped IPv6 Address IPv6 allows embedding an IPv4 address within an IPv6 address. See IPv6 Addresses with Embedded IPv4 Addresses

ip-num offers various ways to create an IPv4-Mapped IPv6 Address:

Converting from an existing IPv4
import { IPv4 } from "ip-num/IPNumber";

let ipv4 = new IPv4("74.125.43.99")
ipv4.toIPv4MappedIPv6().toString() // produces ::ffff:4a7d:2b63
From an existing IPv4 using convenience method on IPv6
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
From dot-decimal notation using convenience method on IPv6
import { IPv6 } from "ip-num/IPNumber";

let ipv6 = IPv6.fromIPv4DotDecimalString("74.125.43.99")
ipv6.toString() // produces ::ffff:4a7d:2b63

IP Pool

Pool allows for working with collections of IP numbers and ranges.

Creating Pools from list of IP numbers and converting to IP 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"

Aggregating IP ranges

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;

Validation and Utilities

Various validation are exposed via the Validator module. ip-num also provide various utility operations. These utility operations can be found in BinaryUtils, IPv6Utils, and HexadecimalUtils.

For example to expand and collapse IPv6 numbers:

import * as IPv6Utils from 'ip-num/IPv6Utils'

// expanding
IPv6Utils.expandIPv6Number("::") // Expands to 0000:0000:0000:0000:0000:0000:0000:0000
IPv6Utils.expandIPv6Number("FF01::101")// Expands to FF01:0000:0000:0000:0000:0000:0000:0101
// collapsing
IPv6Utils.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 the Validator documentation for more information See the BinaryUtils documentation for more information See the IPv6Utils documentation for more information See the HexadecimalUtils documentation for more information

License

The ip-num library is released under the MIT license

Contributing

To discuss a new feature or ask a question, open an issue. Find the issue tracker here

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.

Change log

View latest releases here

v1.2.1
v1.2.0
  • 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
v1.1.1
  • 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 string Issue #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
v1.1.0

Version 1.1.0 was Unpublished.

v1.0.1
  • Renamed Subnet to SubnetMask Issue #1
  • Fixed the throwing of invalid integer: NaN when invalid IPv4 and IPv6 strings are passed to Validator .isValidIPv4String and Validator.isValidIPv6String validators. Fixed by saiyeek Issue #5
  • Fixed Validator.isValidIPv4CidrNotation improper validation of IPv4 CIDR Issue #6

Acknowledgement

Special thanks to JetBrains for supporting the development of ip-num with a free IDE licence.

You can find more information about JetBrains support for open source projects here

ip-num's People

Contributors

chri-sche avatar dadepo avatar dependabot[bot] avatar dwarburt avatar lenovouser avatar wibisono avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ip-num's Issues

Subrange, CIDR based iteration of ranges

Make it possible to iterate over a range, producing cidr subranges.

for subrange(/18) as s in range(10.0.0.0/16):
      print s

Should print:

10.0.0.0/18
10.0.64.0/18
10.0.128.0/18
10.0.192.0/18

Add ability to validate if a CIDR notation represents a valid range

The IP number portion of a cidr notation should signify the start of the range (or the network identifier)

Add a validation method that returns true or false depending on if the given ip number represents the start of the range.

validate 10.0.0.0/8 -> should return true, since 10.0.0.0 is the start of the range depicted
validate 10.0.4.23/8 -> should return false, since 10.0.4.23/8 is not the start of the range.

Add method to split range into smaller ranges of certain size

For example:

import { IPv6CidrRange, IPv6Prefix } from 'ip-num';

const range = IPv6CidrRange.fromCidr('2001:db8::/29');

const prefix = new IPv6Prefix(32);

range.split(prefix);

would yield (in CIDR format):

const result = [
    '2001:db8::/32',
    '2001:db9::/32',
    '2001:dba::/32',
    '2001:dbb::/32',
    '2001:dbc::/32',
    '2001:dbd::/32',
    '2001:dbe::/32',
    '2001:dbf::/32',
];

Collapsing already collapsed IPv6 returns invalid IPv6 addr

Collapsing an already collapsed IPv6 address returns an invalid IPv6 address. This is important to collapse an IPv6 address, when it is not known if the address is already collapsed.

Example (v. 1.3.2):

var ipNum = require("ip-num")
ipNum.collapseIPv6Number("2123:470:1:b95::7316");
--> "2123:470:1:b95:0:7316"

Ipv6 from mapped ipv4.

I think Ipv6 from mapped ipv4 will be good feature.

// It works.
new IPv6('::ffff:4a7d:2b63');

// But, it doesn't work.
new IPv6('::ffff:74.125.43.99');

Add support for ES6 module imports

This library is fantastic. ESM module imports are now supported by major browsers. It would be really convenient to add support for such imports with ip-num.

Improve release pipeline

  1. Automatically bump up version as part of the release process
  2. Automatically tag with release number as part of the release process
  3. Make sure the docs are automatically updated and committed as part of the release process
  4. Make sure the compiled JS and JS map is available as part of the release process

Implement takeStream, takeStreamUntil and takeStreamWhile (including versions starting from last IP) for IPv4 and IPv6 ranges

  1. takeStream(count?: number):
    Return a stream of IP starting from the first up until the optional count. If count is not given, return till the last.

  2. takeStreamUntil(ip: IPv4 | IPv6):
    Return a stream of IP starting from the first up until the given IP

  3. takeStreamWhile(predicate: (IPv4 | IPv6) => boolean)
    Return a stream of IP starting from the first up until the given predicate returns false

  4. takeLastStream(count?: number): Return the last count values from the IP range.
    Return a stream of IP starting from the last up until the optional count. If count is not given, return till the first.

  5. takeLastStreamUntil(ip: IPv4 | IPv6)
    Return a stream of IP starting from the last up until the given IP

  6. takeLastStreamWhile(predicate: (IPv4 | IPv6) => boolean)
    Return a stream of IP starting from the last up until the given predicate returns false

Getting bit size from IPv4Subnet

(new IPv4SubnetMask('255.255.0.0')).prefix

This should equal 16 (since 255.255.0.0 is a /16) but the code above returns 32 (no matter what net mask is provided). Is there a better way to get the correct bit size? This is using version 1.2.2

RangedSet.isCidrAble() incorrect results

import ipNum from "ip-num";

const range = ipNum.RangedSet.fromRangeString( "1.2.3.4-1.2.3.4" );

console.log( range.isCidrAble() ); // false

Why it is false? This range can be presented as 1.2.3.4/32;

Use union types for return values

Most of the return values in Validator returns values of shape [boolean, string[]] where boolean is used to indicate successful or failed validation, and string[] is empty if validation is successful, and contains list of errors if validation failed.

union types can be used to model the return types as boolean | string[] or even boolean | mycustomerrortype

Multiple "::" not considered invalid

I noticed that invalid IPv6 values with 2 sets of "::" are not marked as in valid and are converted. But per the IPv6 specs only one "::" is allowed, because you can't tell how many 0s "::" should be expanded to if there are 2 "::"s. For example, I would have expected each of the following to not be considered valid:

console.log(ipNum.expandIPv6Number("::123::"));
console.log(ipNum.collapseIPv6Number("12::123::"));
console.log(ipNum.Validator.isValidIPv6String("::123::234")[0]);

"0000:0000:0000:0000:0000:0000:0000:0123"
"12:0:123::"
true

Hopefully this is helpful.

Have a proper representation for masking

Right now there is a class called Subnetmask which has contiguous 1's followed by contiguous 0's. This is not totally an accurate representation because there is the concept of network mask, which is different from subnet mask. So a better name would be just Mask.

Or maybe remove totally as this can be represented by the Prefix type.

Introduce data type and operations for working with a set of IP numbers

Create a data structure that can hold ip numbers and support the following operations:

Construction

  • Ability to create the data type from an IP Range
  • Ability to create the data type by specifying a List of IP Range
  • Ability to create the data type by specifying a comma separated enumerations of IP ranges
  • Ability to create the data type by specifying list of IP numbers
  • Ability to create the data type by specifying a comma separated enumerations of IP numbers

Addition and Removal

  • Ability to add/remove an IP range from the data type
  • Ability to add/remove an IP number from the data type

Contains check

  • Ability to tell if a given IP range is in the data type
  • Ability to tell if a given IP number is in the data type

Reduce/Fold Operation

  • Ability to fold the data type into a list where when possible, merge ip numbers at bit boundaries into IP ranges, and IP ranges at bit boundaries into a single IP range.

Intersection

  • Ability to get a list of IP numbers that are common within the IP numbers found in another data type
    !Intersection
  • Ability to get a list of IP numbers that are not common within the IP numbers found in another data type

Supersets and subsets

  • Ability to tell if one instance of this data type is a superset or subset of another instance

Convert to IP range

  • Ability to convert to an IP range. Should only work when ip numbers in the data type are contiguous

Test if IP numbers are contiguous

Comparison operations

  • Ability to tell if one data type is less than, equal to, or greater than another one

IPv6 binary string is converted in a wrong way

The method "binaryStringToHexadecatets" the IPv6.ts file splits the binary string in a wrong manner:
The binary string "10000000000000000" will be translated to 0x10000. This string will be splitted into ["1000", "0"]
The right splitting is ["1", "0000"]

To modify this, ensure, that the incoming hexstring has always a length of 32 characters.

Unfortunately I cannot suggest the change:

private binaryStringToHexadecatets(binaryString: string): Hexadecatet[] {
	let hexadecimalString = binaryStringToHexadecimalString(binaryString);
	while (hexadecimalString.length<32) {
		hexadecimalString = '0'+hexadecimalString;
	}
	let hexadecimalStrings: string[] = hexadecimalString.match(/.{1,4}/g)!;
	return hexadecimalStrings.map((stringHexadecatet)=> {
		return Hexadecatet.fromString(stringHexadecatet);
	});
}

Native BigInt

Hi.
Why not just use native BigInt class instead of big-integer package?
It is stable and appareared since node v10.

Some IPv6 addresses cause parsing errors

When using

new IPv6("::ffff:172.20.0.6");

I get an error:

Error: Given string is already longer than given final length after padding: 4
leftPadWithZeroBit BinaryUtils.js:68
paddedArray IPv6Utils.js:16
expandWithZero IPv6Utils.js:15
expandIPv6Number IPv6Utils.js:40
IPv6 IPNumber.js:537

With some research I found that the standard (not sure if there is a standard?) notation for this would be 0:0:0:0:0:ffff:ac14:6. Would it be possible for the IPv6 method to handle this case if its just a different notation?

Unify the iterable and iteration abilities across data structures that should be iterated

Problem:

Currently the Data structure representing CIDR range is an iterable, while data structure representing IP numbers, although could be iterable is, currently not.

Data structure for CIDR ranges have some sort of stream-like interface for example *take(count?: number) while the data structure representing IP numbers do not, even though they could.

The *take(count?: number) was added ad-hoc fashion. The ReactiveX API has a standard API from which API's like take can be modelled after.

Solution:

  • Make data structure representing IP numbers also iterable. Related to #44
  • Take a look at the ReactiveX API and borrow (integrate) ideas from there to implement the stream like API for ranges and IP numbers. Related to #30

Include abstraction for describing contiguous IP numbers

Sometimes it is needed to work with IP numbers as a contiguous series, but one that is not a CIDR range. For example, when dealing with a sequence of ASN numbers for instance, or for whatever use case, express a range of IPv4 numbers that consist only of 3 IP numbers (something that is not possible in a CIDR notation).

It should be possible to deal with this sort of "ranges".

Custom nextIPNumber / previousIPNumber [IPv4 / IPv6]

Hello,
I've got proposal to extend functionality of (nextIPNumber / previousIPNumber).
We can pass optional argument i.e. count into previous method and based on that count, generate next (or previous) ip number increased (or decreased) by this count.

Examples:

IPv4

init IP Number: 192.168.1.1
count: 10
next IP Number: 192.168.1.11
previous IP Number: 192.168.0.247

IPv6

init IP Number: 1::1
count: 10
next IP Number: 1000:0:0:0:0:0:b
previous IP Number: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff7

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.