mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-20 14:56:17 -04:00
feat(new-tool): ipv4 address converter
This commit is contained in:
parent
8930e139b2
commit
28145e0ffe
5 changed files with 152 additions and 1 deletions
|
@ -1,6 +1,7 @@
|
||||||
import { tool as base64FileConverter } from './base64-file-converter';
|
import { tool as base64FileConverter } from './base64-file-converter';
|
||||||
import { tool as base64StringConverter } from './base64-string-converter';
|
import { tool as base64StringConverter } from './base64-string-converter';
|
||||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||||
|
import { tool as ipv4AddressConverter } from './ipv4-address-converter';
|
||||||
import { tool as benchmarkBuilder } from './benchmark-builder';
|
import { tool as benchmarkBuilder } from './benchmark-builder';
|
||||||
import { tool as userAgentParser } from './user-agent-parser';
|
import { tool as userAgentParser } from './user-agent-parser';
|
||||||
import { tool as ipv4SubnetCalculator } from './ipv4-subnet-calculator';
|
import { tool as ipv4SubnetCalculator } from './ipv4-subnet-calculator';
|
||||||
|
@ -103,7 +104,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Network',
|
name: 'Network',
|
||||||
components: [ipv4SubnetCalculator, macAddressLookup],
|
components: [ipv4SubnetCalculator, ipv4AddressConverter, macAddressLookup],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Math',
|
name: 'Math',
|
||||||
|
|
12
src/tools/ipv4-address-converter/index.ts
Normal file
12
src/tools/ipv4-address-converter/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Binary } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'Ipv4 address converter',
|
||||||
|
path: '/ipv4-address-converter',
|
||||||
|
description: 'Convert an ip address into decimal, binary, hexadecimal or event in ipv6',
|
||||||
|
keywords: ['ipv4', 'address', 'converter', 'decimal', 'hexadecimal', 'binary', 'ipv6'],
|
||||||
|
component: () => import('./ipv4-address-converter.vue'),
|
||||||
|
icon: Binary,
|
||||||
|
createdAt: new Date('2023-04-08'),
|
||||||
|
});
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { expect, describe, it } from 'vitest';
|
||||||
|
import { isValidIpv4, ipv4ToInt } from './ipv4-address-converter.service';
|
||||||
|
|
||||||
|
describe('ipv4-address-converter', () => {
|
||||||
|
describe('ipv4ToInt', () => {
|
||||||
|
it('should convert an IPv4 address to an integer', () => {
|
||||||
|
expect(ipv4ToInt({ ip: '192.168.0.1' })).toBe(3232235521);
|
||||||
|
expect(ipv4ToInt({ ip: '10.0.0.1' })).toBe(167772161);
|
||||||
|
expect(ipv4ToInt({ ip: '255.255.255.255' })).toBe(4294967295);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isValidIpv4', () => {
|
||||||
|
it('should return true for a valid IP address', () => {
|
||||||
|
expect(isValidIpv4({ ip: '192.168.0.1' })).to.equal(true);
|
||||||
|
expect(isValidIpv4({ ip: '10.0.0.1' })).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an invalid IP address', () => {
|
||||||
|
expect(isValidIpv4({ ip: '256.168.0.1' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '192.168.0' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '192.168.0.1.2' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '192.168.0.1.' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '.192.168.0.1' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '192.168.0.a' })).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for crap as input', () => {
|
||||||
|
expect(isValidIpv4({ ip: '' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: ' ' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: 'foo' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '-1' })).to.equal(false);
|
||||||
|
expect(isValidIpv4({ ip: '0' })).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,38 @@
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export { ipv4ToInt, ipv4ToIpv6, isValidIpv4 };
|
||||||
|
|
||||||
|
function ipv4ToInt({ ip }: { ip: string }) {
|
||||||
|
if (!isValidIpv4({ ip })) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip
|
||||||
|
.trim()
|
||||||
|
.split('.')
|
||||||
|
.reduce((acc, part, index) => acc + Number(part) * Math.pow(256, 3 - index), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ipv4ToIpv6({ ip, prefix = '0000:0000:0000:0000:0000:ffff:' }: { ip: string; prefix?: string }) {
|
||||||
|
if (!isValidIpv4({ ip })) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
prefix +
|
||||||
|
_.chain(ip)
|
||||||
|
.trim()
|
||||||
|
.split('.')
|
||||||
|
.map((part) => parseInt(part).toString(16).padStart(2, '0'))
|
||||||
|
.chunk(2)
|
||||||
|
.map((blocks) => blocks.join(''))
|
||||||
|
.join(':')
|
||||||
|
.value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidIpv4({ ip }: { ip: string }) {
|
||||||
|
const cleanIp = ip.trim();
|
||||||
|
|
||||||
|
return /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/.test(cleanIp);
|
||||||
|
}
|
64
src/tools/ipv4-address-converter/ipv4-address-converter.vue
Normal file
64
src/tools/ipv4-address-converter/ipv4-address-converter.vue
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<n-form-item label="An ipv4 address:" v-bind="validationAttrs">
|
||||||
|
<n-input v-model:value="rawIpAddress" placeholder="An ipv4 address..." />
|
||||||
|
</n-form-item>
|
||||||
|
|
||||||
|
<n-divider style="margin-top: 0" mt-0 />
|
||||||
|
|
||||||
|
<n-form-item
|
||||||
|
v-for="{ label, value } of convertedSections"
|
||||||
|
:key="label"
|
||||||
|
:label="label"
|
||||||
|
label-placement="left"
|
||||||
|
label-width="100"
|
||||||
|
>
|
||||||
|
<input-copyable
|
||||||
|
:value="validationAttrs.validationStatus === 'error' ? '' : value"
|
||||||
|
placeholder="Set a correct ipv4 address"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useValidation } from '@/composable/validation';
|
||||||
|
import { convertBase } from '../integer-base-converter/integer-base-converter.model';
|
||||||
|
import { ipv4ToInt, ipv4ToIpv6, isValidIpv4 } from './ipv4-address-converter.service';
|
||||||
|
|
||||||
|
const rawIpAddress = ref('192.168.1.1');
|
||||||
|
|
||||||
|
const convertedSections = computed(() => {
|
||||||
|
const ipInDecimal = ipv4ToInt({ ip: rawIpAddress.value });
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'Decimal : ',
|
||||||
|
value: String(ipInDecimal),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Hexadecimal: ',
|
||||||
|
value: convertBase({ fromBase: 10, toBase: 16, value: String(ipInDecimal) }).toUpperCase(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Binary: ',
|
||||||
|
value: convertBase({ fromBase: 10, toBase: 2, value: String(ipInDecimal) }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ipv6: ',
|
||||||
|
value: ipv4ToIpv6({ ip: rawIpAddress.value }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ipv6 (short): ',
|
||||||
|
value: ipv4ToIpv6({ ip: rawIpAddress.value, prefix: '::ffff:' }),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
const { attrs: validationAttrs } = useValidation({
|
||||||
|
source: rawIpAddress,
|
||||||
|
rules: [{ message: 'Invalid ipv4 address', validator: (ip) => isValidIpv4({ ip }) }],
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
Loading…
Add table
Add a link
Reference in a new issue