feat(MAC Address Converter): add EUI-64 and IPv6 support

Fix #1146
This commit is contained in:
ShareVB 2024-06-16 13:50:56 +02:00
parent d14371c5c2
commit 743757761d
3 changed files with 106 additions and 7 deletions

View file

@ -1,15 +1,30 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { convertMacCISCO, convertMacCanonical, convertMacCanonicalIEEE, convertMacCanonicalIETF } from './mac-address-converter.service'; import {
convertMacCISCO, convertMacCanonical,
convertMacCanonicalIEEE, convertMacCanonicalIETF,
convertMacToEUI64CISCO, convertMacToEUI64CanonicalIEEE,
convertMacToEUI64CanonicalIETF, convertMacToLinkLocalIPv6,
convertMacToNumber,
} from './mac-address-converter.service';
describe('mac-address-converter', () => { describe('mac-address-converter', () => {
it('Convert MAC Address to given format', async () => { it('Convert MAC Address to given format', async () => {
expect(convertMacCanonical('')).to.equal(''); expect(convertMacCanonical('')).to.equal('');
const macValue = 'AA:BB:CC:DD:EE:FF'; const macValue = '00:0a:95:9d:68:16';
expect(convertMacCanonicalIETF(macValue)).to.equal('aa:bb:cc:dd:ee:ff'); expect(convertMacCanonicalIETF(macValue)).to.equal('00:0a:95:9d:68:16');
expect(convertMacCanonical(macValue)).to.equal('AA.BB.CC.DD.EE.FF'); expect(convertMacCanonical(macValue)).to.equal('00.0a.95.9d.68.16');
expect(convertMacCanonicalIEEE(macValue)).to.equal('AA-BB-CC-DD-EE-FF'); expect(convertMacCanonicalIEEE(macValue)).to.equal('00-0A-95-9D-68-16');
expect(convertMacCISCO(macValue)).to.equal('aabb.ccdd.eeff'); expect(convertMacCISCO(macValue)).to.equal('000a.959d.6816');
expect(convertMacToEUI64CanonicalIETF(macValue, true)).to.equal('02:0a:95:ff:fe:9d:68:16');
expect(convertMacToEUI64CanonicalIETF(macValue, false)).to.equal('00:0a:95:ff:fe:9d:68:16');
expect(convertMacToEUI64CanonicalIEEE(macValue, true)).to.equal('02-0A-95-FF-FE-9D-68-16');
expect(convertMacToEUI64CanonicalIEEE(macValue, false)).to.equal('00-0A-95-FF-FE-9D-68-16');
expect(convertMacToEUI64CISCO(macValue, true)).to.equal('020a.95ff.fe9d.6816');
expect(convertMacToEUI64CISCO(macValue, false)).to.equal('000a.95ff.fe9d.6816');
expect(convertMacToNumber(macValue)).to.equal(45459793942);
expect(convertMacToLinkLocalIPv6(macValue)).to.equal(':fe80::20a:95ff:fe9d:6816');
}); });
}); });

View file

@ -3,6 +3,48 @@ function convertMac(mac: string, group: number = 2, char: string = ':'): string
return mac.match(new RegExp(`.{1,${group}}`, 'g'))?.join(char) || ''; return mac.match(new RegExp(`.{1,${group}}`, 'g'))?.join(char) || '';
} }
function convertMacToEUI64(mac: string, ipv6: boolean) {
const macIETF = convertMac(mac);
// Split the MAC address into an array of hex values
const macArray = macIETF.split(':').map(hex => Number.parseInt(hex, 16));
// For IPv6, invert the 7th bit of the first byte
if (ipv6) {
macArray[0] ^= 0x02;
}
// Insert FFFE in the middle
const eui64Array = [
macArray[0], macArray[1], macArray[2],
0xFF, 0xFE,
macArray[3], macArray[4], macArray[5],
];
// Convert the array to a colon-separated string
const eui64 = eui64Array.map(byte => byte.toString(16).padStart(2, '0')).join(':');
// Group into IPv6 EUI-64 format (XXXX:XXFF:FEXX:XXXX)
return eui64.replace(/:/g, '').match(/.{1,4}/g)!.join(':');
}
export function convertMacToEUI64CanonicalIETF(mac: string, ipv6: boolean) {
return convertMac(convertMacToEUI64(mac, ipv6).toLocaleLowerCase());
}
export function convertMacToEUI64CanonicalIEEE(mac: string, ipv6: boolean) {
return convertMac(convertMacToEUI64(mac, ipv6).toLocaleUpperCase(), 2, '-');
}
export function convertMacToEUI64CISCO(mac: string, ipv6: boolean) {
return convertMac(convertMacToEUI64(mac, ipv6).toLocaleLowerCase(), 4, '.');
}
export function convertMacToLinkLocalIPv6(mac: string) {
return `:fe80::${convertMac(convertMacToEUI64(mac, true).toLocaleLowerCase(), 4, ':').replace(/^0/g, '')}`;
}
export function convertMacToNumber(mac: string) {
mac = mac.replace(/[\W_]+/g, '');
return Number.parseInt(mac, 16);
}
export function convertMacCanonicalIETF(mac: string): string { export function convertMacCanonicalIETF(mac: string): string {
return convertMac(mac.toLocaleLowerCase()); return convertMac(mac.toLocaleLowerCase());
}; };

View file

@ -1,6 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import InputCopyable from '../../components/InputCopyable.vue'; import InputCopyable from '../../components/InputCopyable.vue';
import { convertMacCISCO, convertMacCanonical, convertMacCanonicalIEEE, convertMacCanonicalIETF } from './mac-address-converter.service'; import {
convertMacCISCO, convertMacCanonical,
convertMacCanonicalIEEE, convertMacCanonicalIETF,
convertMacToEUI64CISCO, convertMacToEUI64CanonicalIEEE,
convertMacToEUI64CanonicalIETF, convertMacToLinkLocalIPv6,
convertMacToNumber,
} from './mac-address-converter.service';
const input = ref('AA:BB:CC:DD:EE:FF'); const input = ref('AA:BB:CC:DD:EE:FF');
@ -21,6 +27,42 @@ const formats = computed(() => [
label: 'Cisco:', label: 'Cisco:',
value: convertMacCISCO(input.value), value: convertMacCISCO(input.value),
}, },
{
label: 'Hex:',
value: convertMacToNumber(input.value).toString(16),
},
{
label: 'Decimal:',
value: convertMacToNumber(input.value).toString(10),
},
{
label: 'EUI-64 Canonical IETF Format:',
value: convertMacToEUI64CanonicalIETF(input.value, false),
},
{
label: 'EUI-64 Canonical IEEE Format:',
value: convertMacToEUI64CanonicalIEEE(input.value, false),
},
{
label: 'EUI-64 Cisco:',
value: convertMacToEUI64CISCO(input.value, false),
},
{
label: 'EUI-64 IPv6 Canonical IETF Format:',
value: convertMacToEUI64CanonicalIETF(input.value, true),
},
{
label: 'EUI-64 IPv6 Canonical IEEE Format:',
value: convertMacToEUI64CanonicalIEEE(input.value, true),
},
{
label: 'EUI-64 IPv6 Cisco:',
value: convertMacToEUI64CISCO(input.value, true),
},
{
label: 'Link-Local IPv6:',
value: convertMacToLinkLocalIPv6(input.value),
},
]); ]);
const inputLabelAlignmentConfig = { const inputLabelAlignmentConfig = {