aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Corentin Thomasset <corentin.thomasset74@gmail.com> 2023-04-08 21:10:00 +0200
committerGravatar Corentin THOMASSET <corentin.thomasset74@gmail.com> 2023-04-08 21:13:14 +0200
commit28145e0ffeb1f1c97cc503fb1e82ec18e8ebd588 (patch)
tree65ba60a709e4432f30fd0842bcdf5c080bd30a49 /src
parent8930e139b28ff165cca2d818199505a727106466 (diff)
downloadit-tools-28145e0ffeb1f1c97cc503fb1e82ec18e8ebd588.tar.gz
it-tools-28145e0ffeb1f1c97cc503fb1e82ec18e8ebd588.tar.zst
it-tools-28145e0ffeb1f1c97cc503fb1e82ec18e8ebd588.zip
feat(new-tool): ipv4 address converter
Diffstat (limited to 'src')
-rw-r--r--src/tools/index.ts3
-rw-r--r--src/tools/ipv4-address-converter/index.ts12
-rw-r--r--src/tools/ipv4-address-converter/ipv4-address-converter.service.test.ts36
-rw-r--r--src/tools/ipv4-address-converter/ipv4-address-converter.service.ts38
-rw-r--r--src/tools/ipv4-address-converter/ipv4-address-converter.vue64
5 files changed, 152 insertions, 1 deletions
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 8ea8b54..f1d63b7 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,6 +1,7 @@
import { tool as base64FileConverter } from './base64-file-converter';
import { tool as base64StringConverter } from './base64-string-converter';
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 userAgentParser } from './user-agent-parser';
import { tool as ipv4SubnetCalculator } from './ipv4-subnet-calculator';
@@ -103,7 +104,7 @@ export const toolsByCategory: ToolCategory[] = [
},
{
name: 'Network',
- components: [ipv4SubnetCalculator, macAddressLookup],
+ components: [ipv4SubnetCalculator, ipv4AddressConverter, macAddressLookup],
},
{
name: 'Math',
diff --git a/src/tools/ipv4-address-converter/index.ts b/src/tools/ipv4-address-converter/index.ts
new file mode 100644
index 0000000..62d2daf
--- /dev/null
+++ b/src/tools/ipv4-address-converter/index.ts
@@ -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'),
+});
diff --git a/src/tools/ipv4-address-converter/ipv4-address-converter.service.test.ts b/src/tools/ipv4-address-converter/ipv4-address-converter.service.test.ts
new file mode 100644
index 0000000..ecdcfa2
--- /dev/null
+++ b/src/tools/ipv4-address-converter/ipv4-address-converter.service.test.ts
@@ -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);
+ });
+ });
+});
diff --git a/src/tools/ipv4-address-converter/ipv4-address-converter.service.ts b/src/tools/ipv4-address-converter/ipv4-address-converter.service.ts
new file mode 100644
index 0000000..ffd5d80
--- /dev/null
+++ b/src/tools/ipv4-address-converter/ipv4-address-converter.service.ts
@@ -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);
+}
diff --git a/src/tools/ipv4-address-converter/ipv4-address-converter.vue b/src/tools/ipv4-address-converter/ipv4-address-converter.vue
new file mode 100644
index 0000000..2721b1a
--- /dev/null
+++ b/src/tools/ipv4-address-converter/ipv4-address-converter.vue
@@ -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>