feat(new-tool): ipv4 address converter
This commit is contained in:
		
							parent
							
								
									8930e139b2
								
							
						
					
					
						commit
						28145e0ffe
					
				| @ -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', | ||||
|  | ||||
							
								
								
									
										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…
	
		Reference in New Issue
	
	Block a user