Skip to content

Commit 42ce69d

Browse files
committed
Add double regex schema for IBAN number check
1 parent 7da0f6d commit 42ce69d

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

src/lib/string.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ describe("string tests", () => {
126126
[undefined as unknown as string, false],
127127
["CH9300762011623852957", true],
128128
["CH93 0076 2011 6238 5295 7", true],
129+
["CH930076 20116238 5295 7", false],
129130
["CH93-0076-2011-6238-5295-7", false],
130131
["CH93 0000 0000 0000 0000 1", false],
131132
["ch93 0076 2011 6238 5295 7", false],

src/lib/string.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,37 +74,38 @@ export function truncate(value: string | undefined, maxLength: number, suffix =
7474
* @returns The result of the IBAN number check
7575
*/
7676
export function isValidSwissIbanNumber(ibanNumber: string): boolean {
77+
// 1. Reject null, undefined or whitespace-only strings
7778
if (isNullOrWhitespace(ibanNumber)) {
7879
return false;
7980
}
8081

81-
const compactIbanNumberWithWhiteSpaces = new RegExp(/^CH\d{2}(?:\s?\d{4}){4}\s?\d{1}$/);
82+
// 2. Define allowed strict formats
83+
// - with spaces: "CHXX XXXX XXXX XXXX XXXX X"
84+
const compactIbanNumberWithWhiteSpaces = new RegExp(/^CH\d{2}(?: \d{4}){4} \d{1}$/);
85+
// - without spaces: "CHXXXXXXXXXXXXXXXXXXX"
86+
const compactIbanNumberWithoutWhiteSpaces = new RegExp(/^CH\d{19}$/);
8287

83-
if (!compactIbanNumberWithWhiteSpaces.test(ibanNumber)) {
88+
// 3. Check if input matches one of the allowed formats
89+
if (!compactIbanNumberWithWhiteSpaces.test(ibanNumber) && !compactIbanNumberWithoutWhiteSpaces.test(ibanNumber)) {
8490
return false;
8591
}
8692

87-
/**
88-
* Validates a Swiss IBAN number.
89-
*
90-
* Steps:
91-
* - The number must start with `CH`, be 21 digits long and follow one of the accepted formats:
92-
* - `CHXX XXXX XXXX XXXX XXXX X`or `CHXXXXXXXXXXXXXXXXXXX`.
93-
* - Remove all whitespaces.
94-
* - Rearrange by moving the first 4 characters (CH + 2 check digits) to the end.
95-
* - Replace letters with numbers: A=10, B=11, ..., Z=35.
96-
* - Convert the resulting string to a large integer and calculate modulo 97.
97-
* - The number is valid if the resto of the calculation equals 1.
98-
*/
99-
93+
// 4. Remove all spaces to get a compact IBAN string
10094
const compactIbanNumber = ibanNumber.replaceAll(" ", "");
95+
96+
// 5. Rearrange IBAN for checksum calculation
97+
// - move first 4 characters (CH + 2 check digits) to the end
10198
const rearrangedIban = compactIbanNumber.slice(4) + compactIbanNumber.slice(0, 4);
99+
100+
// 6. Replace letters with numbers (A=10, B=11, ..., Z=35)
102101
const numericStr = rearrangedIban.replaceAll(/[A-Z]/g, (ch) => (ch.codePointAt(0)! - 55).toString());
103102

103+
// 7. Perform modulo 97 calculation to validate IBAN
104104
let restOfCalculation = 0;
105105
for (const digit of numericStr) {
106106
restOfCalculation = (restOfCalculation * 10 + Number(digit)) % 97;
107107
}
108108

109+
// 8. IBAN is valid only if the remainder equals 1
109110
return restOfCalculation === 1;
110111
}

0 commit comments

Comments
 (0)