20, 'BE' => 16, 'CH' => 21, 'DE' => 22, 'ES' => 24, 'FR' => 27, 'IT' => 27, 'LU' => 20, 'NL' => 18, ]; public function isValid(string $iban): bool { $normalized = $this->normalize($iban); if (1 !== preg_match('/^[A-Z]{2}[0-9]{2}[A-Z0-9]+$/', $normalized)) { return FALSE; } if (strlen($normalized) !== (self::LENGTHS[substr($normalized, 0, 2)] ?? NULL)) { return FALSE; } return 1 === $this->mod97(substr($normalized, 4) . substr($normalized, 0, 4)); } public function normalize(string $iban): string { return strtoupper(str_replace([' ', '-'], '', $iban)); } private function mod97(string $rearranged): int { $remainder = 0; foreach (str_split($rearranged) as $character) { $digits = ctype_digit($character) ? $character : (string) (ord($character) - 55); foreach (str_split($digits) as $digit) { $remainder = ($remainder * 10 + (int) $digit) % 97; } } return $remainder; } }