mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-23 08:16:16 -04:00
feat(new tool): IPv4/6 in IP Range
This commit is contained in:
parent
80e46c9292
commit
9501a60dc0
5 changed files with 127 additions and 7 deletions
|
@ -62,6 +62,7 @@
|
|||
"highlight.js": "^11.7.0",
|
||||
"iarna-toml-esm": "^3.0.5",
|
||||
"ibantools": "^4.3.3",
|
||||
"ip-matching": "^2.1.2",
|
||||
"json5": "^2.2.3",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"libphonenumber-js": "^1.10.28",
|
||||
|
|
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
|
@ -86,6 +86,9 @@ dependencies:
|
|||
ibantools:
|
||||
specifier: ^4.3.3
|
||||
version: 4.3.3
|
||||
ip-matching:
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2
|
||||
json5:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3
|
||||
|
@ -3374,7 +3377,7 @@ packages:
|
|||
dependencies:
|
||||
'@unhead/dom': 0.5.1
|
||||
'@unhead/schema': 0.5.1
|
||||
'@vueuse/shared': 10.6.1(vue@3.3.4)
|
||||
'@vueuse/shared': 10.9.0(vue@3.3.4)
|
||||
unhead: 0.5.1
|
||||
vue: 3.3.4
|
||||
transitivePeerDependencies:
|
||||
|
@ -4016,10 +4019,10 @@ packages:
|
|||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared@10.6.1(vue@3.3.4):
|
||||
resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==}
|
||||
/@vueuse/shared@10.9.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
|
||||
dependencies:
|
||||
vue-demi: 0.14.6(vue@3.3.4)
|
||||
vue-demi: 0.14.7(vue@3.3.4)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
|
@ -6203,6 +6206,10 @@ packages:
|
|||
jsbn: 1.1.0
|
||||
dev: false
|
||||
|
||||
/ip-matching@2.1.2:
|
||||
resolution: {integrity: sha512-/ok+VhKMasgR5gvTRViwRFQfc0qYt9Vdowg6TO4/pFlDCob5ZjGPkwuOoQVCd5OrMm20zqh+1vA8KLJZTeWudg==}
|
||||
dev: false
|
||||
|
||||
/is-alphabetical@1.0.4:
|
||||
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
|
||||
dev: true
|
||||
|
@ -9200,8 +9207,8 @@ packages:
|
|||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/vue-demi@0.14.6(vue@3.3.4):
|
||||
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
|
||||
/vue-demi@0.14.7(vue@3.3.4):
|
||||
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
|
|
|
@ -75,6 +75,7 @@ import { tool as urlParser } from './url-parser';
|
|||
import { tool as uuidGenerator } from './uuid-generator';
|
||||
import { tool as macAddressLookup } from './mac-address-lookup';
|
||||
import { tool as xmlFormatter } from './xml-formatter';
|
||||
import { tool as ipInRange } from './ip-in-range';
|
||||
|
||||
export const toolsByCategory: ToolCategory[] = [
|
||||
{
|
||||
|
@ -143,7 +144,15 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
},
|
||||
{
|
||||
name: 'Network',
|
||||
components: [ipv4SubnetCalculator, ipv4AddressConverter, ipv4RangeExpander, macAddressLookup, macAddressGenerator, ipv6UlaGenerator],
|
||||
components: [
|
||||
ipv4SubnetCalculator,
|
||||
ipv4AddressConverter,
|
||||
ipInRange,
|
||||
ipv4RangeExpander,
|
||||
macAddressLookup,
|
||||
macAddressGenerator,
|
||||
ipv6UlaGenerator,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Math',
|
||||
|
|
12
src/tools/ip-in-range/index.ts
Normal file
12
src/tools/ip-in-range/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { UnfoldMoreOutlined } from '@vicons/material';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'IP in Range/CIDR/Mask',
|
||||
path: '/ip-in-range',
|
||||
description: 'Given a CIDR/IP Range/Wildcard IP/IP Mask, tell if a given IP is in subnet range',
|
||||
keywords: ['ip', 'cidr', 'range'],
|
||||
component: () => import('./ip-in-range.vue'),
|
||||
icon: UnfoldMoreOutlined,
|
||||
createdAt: new Date('2024-03-09'),
|
||||
});
|
91
src/tools/ip-in-range/ip-in-range.vue
Normal file
91
src/tools/ip-in-range/ip-in-range.vue
Normal file
|
@ -0,0 +1,91 @@
|
|||
<script setup lang="ts">
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { Check as CheckIcon, LetterX as CrossIcon } from '@vicons/tabler';
|
||||
import { getMatch } from 'ip-matching';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import { isNotThrowing } from '@/utils/boolean';
|
||||
import SpanCopyable from '@/components/SpanCopyable.vue';
|
||||
|
||||
const range = useStorage('ip-in-range:range', '192.168.0.1/24'); // NOSONAR
|
||||
const ip = useStorage('ip-in-range:ip', '192.168.0.1'); // NOSONAR
|
||||
|
||||
const match = computed(() => withDefaultOnError(() => getMatch(range.value), undefined));
|
||||
const subnets = computed(() => {
|
||||
return (match.value?.convertToMasks() || []).map((mask) => {
|
||||
const subnet = mask.convertToSubnet();
|
||||
if (!subnet) {
|
||||
return { cidr: '', start: '', end: '' };
|
||||
}
|
||||
return {
|
||||
cidr: subnet.toString(),
|
||||
start: subnet.getFirst().toString(),
|
||||
end: subnet.getLast().toString(),
|
||||
};
|
||||
}).filter(subnet => subnet.cidr !== '');
|
||||
});
|
||||
const ipIsInMatch = computed(() => match.value?.matches(ip.value));
|
||||
|
||||
const ipValidationRules = [
|
||||
{
|
||||
message: 'We cannot parse this CIDR/IP Range/Mask/Wildcard, check the format',
|
||||
validator: (value: string) => isNotThrowing(() => getMatch(value)) && getMatch(range.value),
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-input-text
|
||||
v-model:value="range"
|
||||
label="An IPv4/6 CIDR/Range/Mask/Wildcard"
|
||||
placeholder="The ipv4/6 CIDR..."
|
||||
:validation-rules="ipValidationRules"
|
||||
mb-4
|
||||
/>
|
||||
|
||||
<c-input-text
|
||||
v-model:value="ip"
|
||||
label="An IPv4/6 address"
|
||||
placeholder="The ipv4/6 address..."
|
||||
:validation-rules="ipValidationRules"
|
||||
mb-4
|
||||
/>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<div flex justify-center>
|
||||
<span v-if="ipIsInMatch">
|
||||
<n-icon color="green">
|
||||
<CheckIcon />
|
||||
</n-icon>
|
||||
Match
|
||||
</span>
|
||||
<span v-else>
|
||||
<n-icon color="red">
|
||||
<CrossIcon />
|
||||
</n-icon>
|
||||
Not Match
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<c-card title="Subnets">
|
||||
<n-table>
|
||||
<tbody>
|
||||
<tr v-for="{ cidr, start, end } in subnets" :key="cidr">
|
||||
<td font-bold>
|
||||
<SpanCopyable :value="cidr" />
|
||||
</td>
|
||||
<td>
|
||||
<SpanCopyable :value="start" />
|
||||
</td>
|
||||
<td>
|
||||
<SpanCopyable :value="end" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</c-card>
|
||||
</div>
|
||||
</template>
|
Loading…
Add table
Add a link
Reference in a new issue