mirror of
https://github.com/CorentinTh/it-tools.git
synced 2026-08-30 13:52:05 +00:00
Merge 2acf377ee3 into d505845f91
This commit is contained in:
commit
51985c68de
4 changed files with 216 additions and 3 deletions
19
components.d.ts
vendored
19
components.d.ts
vendored
|
|
@ -88,6 +88,7 @@ declare module '@vue/runtime-core' {
|
|||
HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default']
|
||||
HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.vue')['default']
|
||||
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
||||
IbanGenerator: typeof import('./src/tools/iban-generator/iban-generator.vue')['default']
|
||||
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
||||
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
||||
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
||||
|
|
@ -98,6 +99,7 @@ declare module '@vue/runtime-core' {
|
|||
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
||||
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
||||
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
||||
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
||||
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
||||
|
|
@ -129,19 +131,32 @@ declare module '@vue/runtime-core' {
|
|||
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
||||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||
NAlert: typeof import('naive-ui')['NAlert']
|
||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||
NCode: typeof import('naive-ui')['NCode']
|
||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||
NDivider: typeof import('naive-ui')['NDivider']
|
||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||
NForm: typeof import('naive-ui')['NForm']
|
||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||
NGi: typeof import('naive-ui')['NGi']
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NImage: typeof import('naive-ui')['NImage']
|
||||
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
||||
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
|
||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||
NLayout: typeof import('naive-ui')['NLayout']
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NSpace: typeof import('naive-ui')['NSpace']
|
||||
NProgress: typeof import('naive-ui')['NProgress']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NStatistic: typeof import('naive-ui')['NStatistic']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTable: typeof import('naive-ui')['NTable']
|
||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||
|
|
|
|||
185
src/tools/iban-generator/iban-generator.vue
Normal file
185
src/tools/iban-generator/iban-generator.vue
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import { random } from '@/utils/random';
|
||||
|
||||
const countries = [
|
||||
{ code: 'AL', name: 'Albania', bankCodeLength: 8, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'AD', name: 'Andorra', bankCodeLength: 4, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'AT', name: 'Austria', bankCodeLength: 5, accountNumberLength: 11, prefix: '' },
|
||||
{ code: 'AZ', name: 'Azerbaijan', bankCodeLength: 4, accountNumberLength: 20, prefix: '' },
|
||||
{ code: 'BH', name: 'Bahrain', bankCodeLength: 4, accountNumberLength: 14, prefix: '' },
|
||||
{ code: 'BE', name: 'Belgium', bankCodeLength: 3, accountNumberLength: 9, prefix: '' },
|
||||
{ code: 'BA', name: 'Bosnia and Herzegovina', bankCodeLength: 3, accountNumberLength: 13, prefix: '' },
|
||||
{ code: 'BR', name: 'Brazil', bankCodeLength: 8, accountNumberLength: 13, prefix: '' },
|
||||
{ code: 'BG', name: 'Bulgaria', bankCodeLength: 4, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'CR', name: 'Costa Rica', bankCodeLength: 3, accountNumberLength: 14, prefix: '' },
|
||||
{ code: 'HR', name: 'Croatia', bankCodeLength: 7, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'CY', name: 'Cyprus', bankCodeLength: 3, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'CZ', name: 'Czech Republic', bankCodeLength: 4, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'DK', name: 'Denmark', bankCodeLength: 4, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'DO', name: 'Dominican Republic', bankCodeLength: 4, accountNumberLength: 20, prefix: '' },
|
||||
{ code: 'EE', name: 'Estonia', bankCodeLength: 2, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'FO', name: 'Faroe Islands', bankCodeLength: 4, accountNumberLength: 9, prefix: '' },
|
||||
{ code: 'FI', name: 'Finland', bankCodeLength: 6, accountNumberLength: 7, prefix: '' },
|
||||
{ code: 'FR', name: 'France', bankCodeLength: 5, accountNumberLength: 11, prefix: '' },
|
||||
{ code: 'GE', name: 'Georgia', bankCodeLength: 2, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'DE', name: 'Germany', bankCodeLength: 8, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'GI', name: 'Gibraltar', bankCodeLength: 4, accountNumberLength: 15, prefix: '' },
|
||||
{ code: 'GR', name: 'Greece', bankCodeLength: 3, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'GL', name: 'Greenland', bankCodeLength: 4, accountNumberLength: 9, prefix: '' },
|
||||
{ code: 'GT', name: 'Guatemala', bankCodeLength: 4, accountNumberLength: 20, prefix: '' },
|
||||
{ code: 'HU', name: 'Hungary', bankCodeLength: 3, accountNumberLength: 17, prefix: '' },
|
||||
{ code: 'IS', name: 'Iceland', bankCodeLength: 4, accountNumberLength: 18, prefix: '' },
|
||||
{ code: 'IE', name: 'Ireland', bankCodeLength: 4, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'IL', name: 'Israel', bankCodeLength: 3, accountNumberLength: 19, prefix: '' },
|
||||
{ code: 'IT', name: 'Italy', bankCodeLength: 5, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'JO', name: 'Jordan', bankCodeLength: 4, accountNumberLength: 18, prefix: '' },
|
||||
{ code: 'KZ', name: 'Kazakhstan', bankCodeLength: 3, accountNumberLength: 13, prefix: '' },
|
||||
{ code: 'XK', name: 'Kosovo', bankCodeLength: 4, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'KW', name: 'Kuwait', bankCodeLength: 4, accountNumberLength: 22, prefix: '' },
|
||||
{ code: 'LV', name: 'Latvia', bankCodeLength: 4, accountNumberLength: 13, prefix: '' },
|
||||
{ code: 'LB', name: 'Lebanon', bankCodeLength: 4, accountNumberLength: 20, prefix: '' },
|
||||
{ code: 'LI', name: 'Liechtenstein', bankCodeLength: 5, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'LT', name: 'Lithuania', bankCodeLength: 5, accountNumberLength: 11, prefix: '' },
|
||||
{ code: 'LU', name: 'Luxembourg', bankCodeLength: 3, accountNumberLength: 13, prefix: '' },
|
||||
{ code: 'MK', name: 'North Macedonia', bankCodeLength: 3, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'MT', name: 'Malta', bankCodeLength: 4, accountNumberLength: 18, prefix: '' },
|
||||
{ code: 'MR', name: 'Mauritania', bankCodeLength: 5, accountNumberLength: 15, prefix: '' },
|
||||
{ code: 'MU', name: 'Mauritius', bankCodeLength: 6, accountNumberLength: 19, prefix: '' },
|
||||
{ code: 'MC', name: 'Monaco', bankCodeLength: 5, accountNumberLength: 11, prefix: '' },
|
||||
{ code: 'MD', name: 'Moldova', bankCodeLength: 2, accountNumberLength: 18, prefix: '' },
|
||||
{ code: 'ME', name: 'Montenegro', bankCodeLength: 3, accountNumberLength: 13, prefix: '' },
|
||||
{ code: 'NL', name: 'Netherlands', bankCodeLength: 4, accountNumberLength: 10, prefix: '' },
|
||||
{ code: 'NO', name: 'Norway', bankCodeLength: 4, accountNumberLength: 7, prefix: '' },
|
||||
{ code: 'PK', name: 'Pakistan', bankCodeLength: 4, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'PS', name: 'Palestine', bankCodeLength: 4, accountNumberLength: 21, prefix: '' },
|
||||
{ code: 'PL', name: 'Poland', bankCodeLength: 8, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'PT', name: 'Portugal', bankCodeLength: 4, accountNumberLength: 15, prefix: '' },
|
||||
{ code: 'QA', name: 'Qatar', bankCodeLength: 4, accountNumberLength: 21, prefix: '' },
|
||||
{ code: 'RO', name: 'Romania', bankCodeLength: 4, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'LC', name: 'Saint Lucia', bankCodeLength: 4, accountNumberLength: 24, prefix: '' },
|
||||
{ code: 'SM', name: 'San Marino', bankCodeLength: 5, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'ST', name: 'São Tomé and Príncipe', bankCodeLength: 8, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'SA', name: 'Saudi Arabia', bankCodeLength: 2, accountNumberLength: 18, prefix: '' },
|
||||
{ code: 'RS', name: 'Serbia', bankCodeLength: 3, accountNumberLength: 15, prefix: '' },
|
||||
{ code: 'SC', name: 'Seychelles', bankCodeLength: 4, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'SK', name: 'Slovakia', bankCodeLength: 4, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'SI', name: 'Slovenia', bankCodeLength: 5, accountNumberLength: 8, prefix: '' },
|
||||
{ code: 'ES', name: 'Spain', bankCodeLength: 8, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'SE', name: 'Sweden', bankCodeLength: 3, accountNumberLength: 17, prefix: '' },
|
||||
{ code: 'CH', name: 'Switzerland', bankCodeLength: 5, accountNumberLength: 12, prefix: '' },
|
||||
{ code: 'TL', name: 'Timor-Leste', bankCodeLength: 3, accountNumberLength: 14, prefix: '' },
|
||||
{ code: 'TN', name: 'Tunisia', bankCodeLength: 5, accountNumberLength: 15, prefix: '' },
|
||||
{ code: 'TR', name: 'Turkey', bankCodeLength: 5, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'UA', name: 'Ukraine', bankCodeLength: 6, accountNumberLength: 19, prefix: '' },
|
||||
{ code: 'AE', name: 'United Arab Emirates', bankCodeLength: 3, accountNumberLength: 16, prefix: '' },
|
||||
{ code: 'GB', name: 'United Kingdom', bankCodeLength: 4, accountNumberLength: 14, prefix: '' },
|
||||
{ code: 'VG', name: 'British Virgin Islands', bankCodeLength: 4, accountNumberLength: 16, prefix: '' },
|
||||
];
|
||||
|
||||
const selectedCountry = ref('DE');
|
||||
const bankCode = ref('');
|
||||
const accountNumber = ref('');
|
||||
const iban = ref('');
|
||||
const error = ref('');
|
||||
|
||||
function padLeft(str: string, length: number, char = '0') {
|
||||
return str.padStart(length, char);
|
||||
}
|
||||
|
||||
function randomDigits(length: number) {
|
||||
let digits = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
digits += Math.floor(random() * 10).toString();
|
||||
}
|
||||
return digits;
|
||||
}
|
||||
|
||||
function regenerate() {
|
||||
const country = countries.find(c => c.code === selectedCountry.value);
|
||||
if (!country) {
|
||||
return;
|
||||
}
|
||||
bankCode.value = randomDigits(country.bankCodeLength);
|
||||
accountNumber.value = randomDigits(country.accountNumberLength);
|
||||
iban.value = '';
|
||||
error.value = '';
|
||||
}
|
||||
|
||||
function generateIban() {
|
||||
error.value = '';
|
||||
const country = countries.find(c => c.code === selectedCountry.value);
|
||||
if (!country) {
|
||||
return;
|
||||
}
|
||||
regenerate();
|
||||
|
||||
const bCode = padLeft(bankCode.value, country.bankCodeLength);
|
||||
const aNum = padLeft(accountNumber.value, country.accountNumberLength);
|
||||
const bban = country.prefix + bCode + aNum;
|
||||
const check = calculateCheckDigits(country.code, bban);
|
||||
iban.value = `${country.code}${check}${bban}`;
|
||||
}
|
||||
|
||||
function calculateCheckDigits(countryCode: string, bban: string) {
|
||||
// IBAN check digits according to ISO 7064
|
||||
let replaced = `${bban + countryCode}00`;
|
||||
replaced = replaced.replace(/[A-Z]/g, c => (c.codePointAt(0)! - 55).toString());
|
||||
|
||||
const remainder = BigInt(replaced) % 97n;
|
||||
const check = 98n - remainder;
|
||||
return check.toString().padStart(2, '0');
|
||||
}
|
||||
|
||||
// Generate Intial IBAN and listen for country changes
|
||||
generateIban();
|
||||
|
||||
watch(selectedCountry, () => {
|
||||
generateIban();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div mb-3 flex items-center>
|
||||
<span w-100px>Country </span>
|
||||
<c-select
|
||||
v-model:value="selectedCountry"
|
||||
searchable
|
||||
flex-1
|
||||
:options="countries.map(({ name, code }) => ({ label: name, value: code }))"
|
||||
data-test-id="iban-generator-country-select"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<c-card
|
||||
align-center
|
||||
mb-3
|
||||
flex
|
||||
justify-center
|
||||
>
|
||||
<c-text-copyable
|
||||
style="text-align: center;font-family: monospace"
|
||||
:value="iban"
|
||||
placeholder="Your IBAN"
|
||||
/>
|
||||
</c-card>
|
||||
|
||||
<div flex justify-center gap-3>
|
||||
<c-button @click="generateIban">
|
||||
Refresh
|
||||
</c-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
::v-deep(.iban-display) {
|
||||
textarea {
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
12
src/tools/iban-generator/index.ts
Normal file
12
src/tools/iban-generator/index.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { defineTool } from '../tool';
|
||||
import Bank from '~icons/mdi/bank';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'IBAN Generator',
|
||||
path: '/iban-generator',
|
||||
description: 'Generating valid IBANs for various countries. Useful for testing and development purposes. The generated IBANs are not linked to real bank accounts.',
|
||||
keywords: ['iban', 'generator'],
|
||||
component: () => import('./iban-generator.vue'),
|
||||
icon: Bank,
|
||||
createdAt: new Date('2025-12-04'),
|
||||
});
|
||||
|
|
@ -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 ibanGenerator } from './iban-generator';
|
||||
import { tool as emailNormalizer } from './email-normalizer';
|
||||
|
||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||
|
|
@ -188,7 +189,7 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
},
|
||||
{
|
||||
name: 'Data',
|
||||
components: [phoneParserAndFormatter, ibanValidatorAndParser],
|
||||
components: [phoneParserAndFormatter, ibanValidatorAndParser, ibanGenerator],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue