feat(tool): base converter
This commit is contained in:
		
							parent
							
								
									5cd9997a84
								
							
						
					
					
						commit
						034c686896
					
				| @ -9,6 +9,7 @@ import { tool as cypher } from './encryption'; | ||||
| import { tool as bip39 } from './bip39-generator'; | ||||
| import { tool as dateTimeConverter } from './date-time-converter'; | ||||
| import { tool as gitMemo } from './git-memo'; | ||||
| import { tool as baseConverter } from './integer-base-converter'; | ||||
| 
 | ||||
| export const toolsByCategory: ToolCategory[] = [ | ||||
|   { | ||||
| @ -19,7 +20,7 @@ export const toolsByCategory: ToolCategory[] = [ | ||||
|   { | ||||
|     name: 'Converter', | ||||
|     icon: LockOpen, | ||||
|     components: [dateTimeConverter, romanNumeralConverter], | ||||
|     components: [dateTimeConverter, baseConverter, romanNumeralConverter], | ||||
|   }, | ||||
|   { | ||||
|     name: 'Development', | ||||
|  | ||||
							
								
								
									
										11
									
								
								src/tools/integer-base-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/tools/integer-base-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| import { ArrowsLeftRight } from '@vicons/tabler'; | ||||
| import type { ITool } from '../Tool'; | ||||
| 
 | ||||
| export const tool: ITool = { | ||||
|   name: 'Integer base converter', | ||||
|   path: '/base-converter', | ||||
|   description: 'Convert numver between different bases (decimal, hexadecimal, binary, octale, base64, ...)', | ||||
|   keywords: ['integer', 'number', 'base', 'convertion', 'decimal', 'hexadecimal', 'binary', 'octale', 'base64'], | ||||
|   component: () => import('./integer-base-converter.vue'), | ||||
|   icon: ArrowsLeftRight, | ||||
| }; | ||||
| @ -0,0 +1,17 @@ | ||||
| import { expect, describe, it } from 'vitest'; | ||||
| import { convertBase } from './integer-base-converter.model'; | ||||
| 
 | ||||
| describe('integer-base-converter', () => { | ||||
|   describe('convertBase', () => { | ||||
|     describe('when the input and target bases are between 2 and 64', () => { | ||||
|       it('should convert integer between different bases', () => { | ||||
|         expect(convertBase({ value: '0', fromBase: 2, toBase: 11 })).toEqual('0'); | ||||
|         expect(convertBase({ value: '0', fromBase: 5, toBase: 2 })).toEqual('0'); | ||||
|         expect(convertBase({ value: '0', fromBase: 10, toBase: 16 })).toEqual('0'); | ||||
|         expect(convertBase({ value: '10100101', fromBase: 2, toBase: 16 })).toEqual('a5'); | ||||
|         expect(convertBase({ value: '192654', fromBase: 10, toBase: 8 })).toEqual('570216'); | ||||
|         expect(convertBase({ value: 'zz', fromBase: 64, toBase: 10 })).toEqual('2275'); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,20 @@ | ||||
| export function convertBase({ value, fromBase, toBase }: { value: string; fromBase: number; toBase: number }) { | ||||
|   const range = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'.split(''); | ||||
|   const fromRange = range.slice(0, fromBase); | ||||
|   const toRange = range.slice(0, toBase); | ||||
|   let decValue = value | ||||
|     .split('') | ||||
|     .reverse() | ||||
|     .reduce((carry: number, digit: string, index: number) => { | ||||
|       if (!fromRange.includes(digit)) { | ||||
|         throw new Error('Invalid digit `' + digit + '` for base ' + fromBase + '.'); | ||||
|       } | ||||
|       return (carry += fromRange.indexOf(digit) * Math.pow(fromBase, index)); | ||||
|     }, 0); | ||||
|   let newValue = ''; | ||||
|   while (decValue > 0) { | ||||
|     newValue = toRange[decValue % toBase] + newValue; | ||||
|     decValue = (decValue - (decValue % toBase)) / toBase; | ||||
|   } | ||||
|   return newValue || '0'; | ||||
| } | ||||
							
								
								
									
										68
									
								
								src/tools/integer-base-converter/integer-base-converter.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/tools/integer-base-converter/integer-base-converter.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| <template> | ||||
|     <div> | ||||
|         <n-card> | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 200px;">Input number:</n-input-group-label> | ||||
|                 <n-input-number v-model:value="inputNumber" min="0" /> | ||||
| 
 | ||||
|                 <n-input-group-label style="width: 200px;">Input base:</n-input-group-label> | ||||
|                 <n-input-number v-model:value="inputBase" max="64" min="2" style="width: 100px;" /> | ||||
|             </n-input-group> | ||||
|             <n-divider></n-divider> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 200px;">Binary (2):</n-input-group-label> | ||||
|                 <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 2 })" | ||||
|                     readonly /> | ||||
|             </n-input-group> | ||||
| 
 | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 200px;">Octale (8):</n-input-group-label> | ||||
|                 <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 8 })" | ||||
|                     readonly /> | ||||
|             </n-input-group> | ||||
| 
 | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 200px;">Decimal (10):</n-input-group-label> | ||||
|                 <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 10 })" | ||||
|                     readonly /> | ||||
|             </n-input-group> | ||||
| 
 | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 200px;">Hexadecimal (16):</n-input-group-label> | ||||
|                 <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 16 })" | ||||
|                     readonly /> | ||||
|             </n-input-group> | ||||
| 
 | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 200px;">Base64 (64):</n-input-group-label> | ||||
|                 <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 64 })" | ||||
|                     readonly /> | ||||
|             </n-input-group> | ||||
|             <n-input-group> | ||||
|                 <n-input-group-label style="width: 90px;">Custom:</n-input-group-label> | ||||
|                 <n-input-number style="width: 110px;" v-model:value="outputBase" max="64" min="2" /> | ||||
|                 <n-input :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: outputBase })" | ||||
|                     readonly /> | ||||
|             </n-input-group> | ||||
|         </n-card> | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue' | ||||
| import { convertBase } from './integer-base-converter.model' | ||||
| 
 | ||||
| const inputNumber = ref(42) | ||||
| const inputBase = ref(10) | ||||
| const outputBase = ref(42) | ||||
| 
 | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .n-input-group:not(:first-child) { | ||||
|     margin-top: 5px; | ||||
| } | ||||
| </style> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user