Skip to content

Commit 1f67ba1

Browse files
committed
feat(new tool): IPv6 Subnet Calculator
IPv6 Subnet Calculator Fix CorentinTh#354 and CorentinTh#924
1 parent d7a8c65 commit 1f67ba1

File tree

10 files changed

+285
-111
lines changed

10 files changed

+285
-111
lines changed

components.d.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ declare module '@vue/runtime-core' {
105105
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
106106
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
107107
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
108+
Ipv6SubnetCalculator: typeof import('./src/tools/ipv6-subnet-calculator/ipv6-subnet-calculator.vue')['default']
108109
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
109110
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
110111
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
@@ -127,24 +128,16 @@ declare module '@vue/runtime-core' {
127128
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
128129
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
129130
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
130-
NCode: typeof import('naive-ui')['NCode']
131131
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
132132
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
133-
NDivider: typeof import('naive-ui')['NDivider']
134133
NEllipsis: typeof import('naive-ui')['NEllipsis']
135-
NFormItem: typeof import('naive-ui')['NFormItem']
136-
NGi: typeof import('naive-ui')['NGi']
137-
NGrid: typeof import('naive-ui')['NGrid']
138134
NH1: typeof import('naive-ui')['NH1']
139135
NH3: typeof import('naive-ui')['NH3']
140136
NIcon: typeof import('naive-ui')['NIcon']
141-
NInputNumber: typeof import('naive-ui')['NInputNumber']
142-
NLabel: typeof import('naive-ui')['NLabel']
143137
NLayout: typeof import('naive-ui')['NLayout']
144138
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
145139
NMenu: typeof import('naive-ui')['NMenu']
146-
NScrollbar: typeof import('naive-ui')['NScrollbar']
147-
NSpin: typeof import('naive-ui')['NSpin']
140+
NTable: typeof import('naive-ui')['NTable']
148141
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
149142
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
150143
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@@ -159,6 +152,7 @@ declare module '@vue/runtime-core' {
159152
RouterLink: typeof import('vue-router')['RouterLink']
160153
RouterView: typeof import('vue-router')['RouterView']
161154
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
155+
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
162156
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
163157
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
164158
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"highlight.js": "^11.7.0",
6565
"iarna-toml-esm": "^3.0.5",
6666
"ibantools": "^4.3.3",
67+
"is-cidr": "^5.0.3",
6768
"json5": "^2.2.3",
6869
"jwt-decode": "^3.1.2",
6970
"libphonenumber-js": "^1.10.28",

pnpm-lock.yaml

Lines changed: 28 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/libs/ip_calculator/ip.js renamed to src/libs/ip_calculator/ip.ts

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ const IPv6MAX = (BigInt(2) ** BigInt(128)) - BigInt(1);
1313
*/
1414

1515
export default class IP {
16+
integer: bigint;
17+
short: string;
18+
version: number;
19+
address: string;
1620
/**
1721
* @constructor
1822
*/
19-
constructor(address) {
20-
this.integer = 0;
21-
this.short = 0;
23+
constructor(address: string) {
24+
this.integer = 0n;
25+
this.short = '';
2226
this.version = this._checkVersion(address);
2327
this.address = this._checkAddress(address, this.version);
2428
}
@@ -34,7 +38,7 @@ export default class IP {
3438
if (this.version === 4) {
3539
const splittedAddr = this.address.split('.').reverse();
3640
bigInt = splittedAddr.reduce((bigInt, octet, index) => {
37-
return (octet * 256 ** index + bigInt
41+
return (Number(octet) * 256 ** index + bigInt
3842
);
3943
}, 0);
4044
}
@@ -51,7 +55,7 @@ export default class IP {
5155
* @param {bigint} bigInt
5256
* @return {string} -> "184.170.96.196"
5357
*/
54-
toDottedNotation(bigInt) {
58+
toDottedNotation(bigInt: bigint) {
5559
if (this.version === 4) {
5660
return (
5761
[(bigInt >> BigInt(24) & BigInt(255)), (bigInt >> BigInt(16) & BigInt(255)),
@@ -78,15 +82,14 @@ export default class IP {
7882
* @return {string} -> 01111111000000000000000000000001
7983
*/
8084
toBinary() {
81-
if (this.integer === 0) {
85+
if (this.integer === 0n) {
8286
this.toInteger();
8387
}
8488
let binary = this.integer.toString(2);
85-
const v = this.version;
86-
const marks = { 4: 32, 6: 128 };
89+
const markLen = this.version === 4 ? 32 : 128;
8790

88-
if (binary.length < marks[v]) {
89-
while (binary.length < marks[v]) {
91+
if (binary.length < markLen) {
92+
while (binary.length < markLen) {
9093
binary = `0${binary}`;
9194
}
9295
}
@@ -98,7 +101,7 @@ export default class IP {
98101
* @return {string} -> 7f000001
99102
*/
100103
toHEX() {
101-
if (this.integer === 0) {
104+
if (this.integer === 0n) {
102105
this.toInteger();
103106
}
104107
return this.integer.toString(16);
@@ -109,7 +112,7 @@ export default class IP {
109112
* IP('127.1.0.0').toCompressed
110113
* @return {string} -> "127.1"
111114
*/
112-
toCompressed(addr, ver) {
115+
toCompressed(addr: string, ver: number) {
113116
if (ver === 4) {
114117
const splittedAddr = addr.split('.');
115118
const sRange = [[1, 3], [2, 2], [3, 1], [0, 0]];
@@ -132,11 +135,11 @@ export default class IP {
132135
// 'N/A' - _longestZerosGroup fn return in case if there is NO
133136
// '0000' blocks in address
134137
if (startOfLongest !== 'N/A' || longestLength !== 'N/A') {
135-
splitted.splice(startOfLongest, longestLength, '');
138+
splitted.splice(Number(startOfLongest), Number(longestLength), '');
136139
if (startOfLongest === 0) {
137140
splitted.unshift('');
138141
}
139-
if (startOfLongest + longestLength === 8) {
142+
if (Number(startOfLongest) + Number(longestLength) === 8) {
140143
splitted.push('');
141144
}
142145
}
@@ -172,7 +175,7 @@ export default class IP {
172175
* @param {string} addr
173176
* @return {number} -> 4 or 6
174177
*/
175-
_checkVersion(addr) {
178+
_checkVersion(addr: string) {
176179
// matches all possible chars in both versions of IP
177180
const reGen = /^[0-9a-f.:]+$/i;
178181
if (reGen.test(addr)) {
@@ -184,14 +187,14 @@ export default class IP {
184187
const reNum = /^[0-9]+$/;
185188

186189
if (reNum.test(addr)) {
187-
addr = BigInt(addr);
188-
if (addr > IPv6MAX || addr <= 0) {
190+
const parsedAddr = BigInt(addr);
191+
if (parsedAddr > IPv6MAX || parsedAddr <= 0) {
189192
throw new Error('Tips: IP address cant be bigger than 2 to the 128-th power or negative number');
190193
}
191-
else if (addr <= IPv4MAX) {
194+
else if (parsedAddr <= IPv4MAX) {
192195
return 4;
193196
}
194-
else if (addr > IPv4MAX) {
197+
else if (parsedAddr > IPv4MAX) {
195198
return 6;
196199
}
197200
}
@@ -210,18 +213,14 @@ export default class IP {
210213
* @private
211214
* @return {string} as a valid address
212215
*/
213-
_checkAddress(addr, v) {
216+
_checkAddress(addr: string, v: number) {
214217
const reNum = /^[0-9]+$/;
215218
if (reNum.test(addr)) {
216219
this.integer = BigInt(addr);
217220
return this.toDottedNotation(this.integer);
218221
}
219222

220-
const marks = {
221-
4: ['.', this._isIPv4, 4],
222-
6: [':', this._isIPv6, 8],
223-
};
224-
const splittedAddr = addr.split(marks[v][0]);
223+
const splittedAddr = addr.split(v === 4 ? '.' : ':');
225224

226225
if (v === 6 && splittedAddr.length < 8) {
227226
const dbColon = (addr.match(/::/g) || []).length;
@@ -230,8 +229,8 @@ export default class IP {
230229
}
231230
}
232231

233-
if (marks[v][1].call(this, splittedAddr)) { // TODO: make ifs more readable
234-
if (splittedAddr.length === marks[v][2] && this.short === 0) {
232+
if ((v === 4 ? this._isIPv4 : this._isIPv6).call(this, splittedAddr)) { // TODO: make ifs more readable
233+
if (splittedAddr.length === (v === 4 ? 4 : 8) && this.short === '') {
235234
return addr;
236235
}
237236
else {
@@ -248,16 +247,16 @@ export default class IP {
248247
* @private
249248
* @return {boolean} whether splitted address is valid IPv6 or not
250249
*/
251-
_isIPv6(splittedAddr) {
250+
_isIPv6(splittedAddr: string[]) {
252251
if (splittedAddr.length <= 8) {
253252
let checked = false;
254253
const [isShort, cleanedAddr] = this._isShort(splittedAddr);
255254

256255
const regex = /^[0-9a-f]{1,4}$/i;
257-
const isValid = function (hextet) {
256+
const isValid = function (hextet: string) {
258257
return regex.test(hextet);
259258
};
260-
checked = cleanedAddr.every(isValid);
259+
checked = (cleanedAddr as string[]).every(isValid);
261260

262261
if (checked && isShort) {
263262
this.short = splittedAddr.join(':');
@@ -274,13 +273,13 @@ export default class IP {
274273
* @private
275274
* @return {boolean} whether splitted address is valid IPv4 or not
276275
*/
277-
_isIPv4(splittedAddr) {
276+
_isIPv4(splittedAddr: string[]) {
278277
if (splittedAddr.length <= 4) {
279278
if (splittedAddr.length < 4) {
280279
this.short = splittedAddr.join('.');
281280
}
282-
const isValid = function (octet) {
283-
return (!!((octet <= 255 && octet >= 0)));
281+
const isValid = function (octet: string) {
282+
return (!!((Number(octet) <= 255 && Number(octet) >= 0)));
284283
};
285284
return splittedAddr.every(isValid);
286285
}
@@ -295,7 +294,7 @@ export default class IP {
295294
* @param {array} splittedAddr
296295
* @return {array} with both results boolean and cleaned array
297296
*/
298-
_isShort(splittedAddr) {
297+
_isShort(splittedAddr: string[]) {
299298
let isShort = false;
300299
const cleanedAddr = [...splittedAddr];
301300
for (let i = 0; i < cleanedAddr.length; i++) {
@@ -320,7 +319,7 @@ export default class IP {
320319
* @param {array} splittedAddr
321320
* @return {string} -> "0000:0000:0000:0000:0000:0000:0000:0001"
322321
*/
323-
_toRepresentation(splittedAddr) {
322+
_toRepresentation(splittedAddr: string[]) {
324323
if (this.version === 4) {
325324
for (let i = 0; i <= 4; i++) {
326325
if (splittedAddr[i] === '') {
@@ -383,7 +382,7 @@ export default class IP {
383382
* @param {array} zeros
384383
* @return {array} -> [0, 7]
385384
*/
386-
function _longestZerosGroup(splittedAddr) {
385+
function _longestZerosGroup(splittedAddr: string[]) {
387386
let curr = 0;
388387
let currLongest = 0;
389388
let startOfLongest = 0;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[
2+
["0.0.0.0", [8, "This host on this network"]],
3+
["10.0.0.0", [8, "Private-Use"]],
4+
["100.64.0.0", [10, "Shared Address Space"]],
5+
["127.0.0.0", [8, "Loopback"]],
6+
["169.254.0.0", [16, "Link Local"]],
7+
["172.16.0.0", [12, "Private-Use"]],
8+
["192.0.0.0", [24, "IETF Protocol Assignments"]],
9+
["192.0.0.0", [29, "IPv4 Service Continuity Prefix"]],
10+
["192.0.0.8", [32, "IPv4 dummy address"]],
11+
["192.0.0.9", [32, "Port Control Protocol Anycast"]],
12+
["192.0.0.10", [32, "Traversal Using Relays around NAT Anycast"]],
13+
["192.0.0.170", [32, "NAT64/DNS64 Discovery"]],
14+
["192.0.0.171", [32, "NAT64/DNS64 Discovery"]],
15+
["192.0.2.0", [24, "Documentation (TEST-NET-1)"]],
16+
["192.31.196.0", [24, "AS112-v4"]],
17+
["192.52.193.0", [24, "AMT"]],
18+
["192.88.99.0", [24, "Deprecated (6to4 Relay Anycast)"]],
19+
["192.168.0.0", [16, "Private Use"]],
20+
["192.175.48.0", [24, "Direct Delegation AS112 Service"]],
21+
["198.18.0.0", [15, "Benchmarking"]],
22+
["198.51.100.0", [24, "Documentation (TEST-NET-2)"]],
23+
["203.0.113.0", [24, "Documentation (TEST-NET-3)"]],
24+
["240.0.0.0", [4, "Reserved"]],
25+
["255.255.255.255", [32, "Limited Broadcast"]]
26+
]

0 commit comments

Comments
 (0)