@@ -79,111 +79,3 @@ export function splitLine(str: string, removeEmptyEntries: boolean = false): str
7979 const splitted = str . split ( / \r \n | \r | \n / ) ;
8080 return removeEmptyEntries ? splitted . filter ( ( line ) => ! isNullOrWhitespace ( line ) ) : splitted ;
8181}
82-
83- /**
84- * Checks if the provided string is a valid swiss IBAN number
85- * @param ibanNumber The provided IBAN number to check
86- * Must be in one of the following formats:
87- * - "CHXX XXXX XXXX XXXX XXXX X" with whitespaces
88- * - "CHXXXXXXXXXXXXXXXXXXX" without whitespaces
89- * @returns The result of the IBAN number check
90- */
91- export function isValidSwissIbanNumber ( ibanNumber : string ) : boolean {
92- // 1. Reject null, undefined or whitespace-only strings
93- if ( isNullOrWhitespace ( ibanNumber ) ) {
94- return false ;
95- }
96-
97- // 2. Define allowed strict formats
98- // - with spaces: "CHXX XXXX XXXX XXXX XXXX X"
99- const compactIbanNumberWithWhiteSpaces = new RegExp ( / ^ C H \d { 2 } (?: \d { 4 } ) { 4 } \d { 1 } $ / ) ;
100- // - without spaces: "CHXXXXXXXXXXXXXXXXXXX"
101- const compactIbanNumberWithoutWhiteSpaces = new RegExp ( / ^ C H \d { 19 } $ / ) ;
102-
103- // 3. Check if input matches one of the allowed formats
104- if ( ! compactIbanNumberWithWhiteSpaces . test ( ibanNumber ) && ! compactIbanNumberWithoutWhiteSpaces . test ( ibanNumber ) ) {
105- return false ;
106- }
107-
108- // 4. Remove all spaces to get a compact IBAN string
109- const compactIbanNumber = ibanNumber . replaceAll ( " " , "" ) ;
110-
111- // 5. Rearrange IBAN for checksum calculation
112- // - move first 4 characters (CH + 2 check digits) to the end
113- const rearrangedIban = compactIbanNumber . slice ( 4 ) + compactIbanNumber . slice ( 0 , 4 ) ;
114-
115- // 6. Replace letters with numbers (A=10, B=11, ..., Z=35)
116- const numericStr = rearrangedIban . replaceAll ( / [ A - Z ] / g, ( ch ) => ( ch . codePointAt ( 0 ) ! - 55 ) . toString ( ) ) ;
117-
118- // 7. Perform modulo 97 calculation to validate IBAN
119- let restOfCalculation = 0 ;
120- for ( const digit of numericStr ) {
121- restOfCalculation = ( restOfCalculation * 10 + Number ( digit ) ) % 97 ;
122- }
123-
124- // 8. IBAN is valid only if the remainder equals 1
125- return restOfCalculation === 1 ;
126- }
127-
128- /**
129- * Validation of social insurance number with checking the checksum
130- * Validation according to https://www.sozialversicherungsnummer.ch/aufbau-neu.htm
131- * @param socialInsuranceNumber The social insurance number to check
132- * Must be in one of the following formats:
133- * - "756.XXXX.XXXX.XX" with dots as separators
134- * - "756XXXXXXXXXX" with digits only
135- * @returns The result if the social insurance number is valid or not
136- */
137- export function isValidSwissSocialSecurityNumber ( socialInsuranceNumber : string ) : boolean {
138- // 1. Check if input is empty or only whitespace
139- if ( isNullOrWhitespace ( socialInsuranceNumber ) ) {
140- return false ;
141- }
142-
143- /**
144- * 2. Check if input matches accepted formats:
145- * - With dots: 756.XXXX.XXXX.XX
146- * - Without dots: 756XXXXXXXXXX
147- */
148- const socialInsuranceNumberWithDots = new RegExp ( / ^ 7 5 6 \. \d { 4 } \. \d { 4 } \. \d { 2 } $ / ) ;
149- const socialInsuranceNumberWithoutDots = new RegExp ( / ^ 7 5 6 \d { 10 } $ / ) ;
150-
151- if ( ! socialInsuranceNumberWithDots . test ( socialInsuranceNumber ) && ! socialInsuranceNumberWithoutDots . test ( socialInsuranceNumber ) ) {
152- return false ;
153- }
154-
155- // 3. Remove all dots → get a string of 13 digits
156- const compactNumber = socialInsuranceNumber . replaceAll ( "." , "" ) ;
157-
158- /**
159- * 4. Separate digits for checksum calculation
160- * - first 12 digits: used to calculate checksum
161- * - last digit: actual check digit
162- */
163- const digits = compactNumber . slice ( 0 , - 1 ) ;
164- const reversedDigits = [ ...digits ] . reverse ( ) . join ( "" ) ;
165- const reversedDigitsArray = [ ...reversedDigits ] ;
166-
167- /*
168- * 5. Calculate weighted sum for checksum
169- * - Even positions (after reversing) ×3
170- * - Odd positions ×1
171- */
172- let sum = 0 ;
173- for ( const [ i , element ] of reversedDigitsArray . entries ( ) ) {
174- sum += i % 2 === 0 ? Number ( element ) * 3 : Number ( element ) * 1 ;
175- }
176-
177- /*
178- * 6. Calculate expected check digit
179- * - Check digit = value to reach next multiple of 10
180- */
181- const checksum = ( 10 - ( sum % 10 ) ) % 10 ;
182- const checknumber = Number . parseInt ( compactNumber . slice ( - 1 ) ) ;
183-
184- /*
185- * 7. Compare calculated check digit with actual last digit
186- * - If equal → valid AHV number
187- */
188- return checksum === checknumber ;
189- }
0 commit comments