Files
romfast-website/efactura-generator/js/validation/iban.js
Claude Agent 85ccdae2cb sync efactura-generator -> 0.9-beta-14
Mirror sincronizat cu repo canonic /workspace/efactura-generator.
CLAUDE.md: documentat workflow sync + exclude config.json din rsync deploy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 13:02:16 +00:00

64 lines
2.3 KiB
JavaScript

/**
* js/validation/iban.js — PR-VALID-IDS (A10)
* Validare IBAN internațional prin algoritmul ISO 13616 (mod 97).
* Funcție pură, fără efecte secundare, fără dependențe externe.
*/
/**
* Validează un IBAN (orice țară, inclusiv RO).
*
* Algoritm ISO 13616:
* 1. Elimină spații și convertește la uppercase.
* 2. Verifică lungimea minimă (4 caractere).
* 3. Mută primele 4 caractere la sfârșitul șirului.
* 4. Înlocuiește fiecare literă cu echivalentul numeric: A=10, B=11, ..., Z=35.
* 5. Calculează numărul rezultat modulo 97 — trebuie să fie 1.
*
* Lungimi specifice per țară nu sunt forțate (validare structurală generică);
* IBAN-ul RO are 24 caractere, verificat separat cu mesaj specific.
*
* @param {string} value — valoarea brută din câmp
* @returns {{ valid: boolean, message: string }}
*/
export function validateIBAN(value) {
if (!value || value.trim() === '') {
return { valid: true, message: '' }; // câmp gol — valid (nu e required check)
}
// Normalizare: elimină spații, uppercase
const normalized = value.trim().toUpperCase().replace(/\s/g, '');
// Lungime minimă
if (normalized.length < 4) {
return { valid: false, message: 'IBAN invalid: lungime sau check digits' };
}
// Verifică că IBAN-ul conține doar litere și cifre
if (!/^[A-Z0-9]+$/.test(normalized)) {
return { valid: false, message: 'IBAN invalid: caractere nepermise' };
}
// IBAN RO trebuie să aibă exact 24 caractere
if (normalized.startsWith('RO') && normalized.length !== 24) {
return { valid: false, message: 'IBAN invalid: lungime sau check digits' };
}
// Rearanjare: primele 4 caractere la final
const rearranged = normalized.slice(4) + normalized.slice(0, 4);
// Înlocuiește literele cu cifre: A=10 ... Z=35
const numericString = rearranged.replace(/[A-Z]/g, ch => String(ch.charCodeAt(0) - 55));
// Calculează mod 97 pe un număr mare (string chunking pentru a evita overflow)
let remainder = 0;
for (let i = 0; i < numericString.length; i++) {
remainder = (remainder * 10 + parseInt(numericString[i], 10)) % 97;
}
if (remainder !== 1) {
return { valid: false, message: 'IBAN invalid: lungime sau check digits' };
}
return { valid: true, message: '' };
}