| | | 1 | | namespace Buergerportal.Gebuehren; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Einfache Pruefung deutscher IBANs (Laenge, Praefix, Modulo-97-Pruefsumme). |
| | | 5 | | /// |
| | | 6 | | /// HINWEIS FUER DAS PRAXISPROJEKT: |
| | | 7 | | /// Diese Klasse ist bewusst nur TEILWEISE mit Tests abgedeckt. Die Methode |
| | | 8 | | /// <see cref="Formatiere"/> hat absichtlich KEINE Tests. Dadurch zeigt der |
| | | 9 | | /// Coverage-Report eine sichtbare, erklaerbare Luecke (< 100 %), an der |
| | | 10 | | /// sich die Wirkung der Testabdeckung demonstrieren laesst. |
| | | 11 | | /// </summary> |
| | | 12 | | public class IbanPruefer |
| | | 13 | | { |
| | | 14 | | /// <summary> |
| | | 15 | | /// Prueft, ob eine deutsche IBAN formal gueltig ist. Leerzeichen werden |
| | | 16 | | /// ignoriert. Gross-/Kleinschreibung ist egal. |
| | | 17 | | /// </summary> |
| | | 18 | | public bool IstGueltig(string? iban) |
| | 10 | 19 | | { |
| | 10 | 20 | | if (string.IsNullOrWhiteSpace(iban)) |
| | 3 | 21 | | { |
| | 3 | 22 | | return false; |
| | | 23 | | } |
| | | 24 | | |
| | 7 | 25 | | var bereinigt = iban.Replace(" ", "").ToUpperInvariant(); |
| | | 26 | | |
| | 7 | 27 | | if (bereinigt.Length != 22) |
| | 3 | 28 | | { |
| | 3 | 29 | | return false; |
| | | 30 | | } |
| | | 31 | | |
| | 4 | 32 | | if (!bereinigt.StartsWith("DE")) |
| | 0 | 33 | | { |
| | 0 | 34 | | return false; |
| | | 35 | | } |
| | | 36 | | |
| | 4 | 37 | | return Modulo97(bereinigt) == 1; |
| | 10 | 38 | | } |
| | | 39 | | |
| | | 40 | | /// <summary> |
| | | 41 | | /// Fuehrt die Modulo-97-Pruefung nach ISO 13616 durch: die ersten vier |
| | | 42 | | /// Zeichen ans Ende stellen, Buchstaben in Zahlen wandeln, Rest zu 97. |
| | | 43 | | /// </summary> |
| | | 44 | | private static int Modulo97(string iban) |
| | 4 | 45 | | { |
| | 4 | 46 | | var umgestellt = iban.Substring(4) + iban.Substring(0, 4); |
| | | 47 | | |
| | 4 | 48 | | var ziffern = new System.Text.StringBuilder(); |
| | 188 | 49 | | foreach (var c in umgestellt) |
| | 88 | 50 | | { |
| | 88 | 51 | | if (char.IsLetter(c)) |
| | 8 | 52 | | { |
| | | 53 | | // A=10, B=11, ... Z=35 |
| | 8 | 54 | | ziffern.Append((c - 'A' + 10).ToString()); |
| | 8 | 55 | | } |
| | | 56 | | else |
| | 80 | 57 | | { |
| | 80 | 58 | | ziffern.Append(c); |
| | 80 | 59 | | } |
| | 88 | 60 | | } |
| | | 61 | | |
| | | 62 | | // Stueckweise Modulo, um Ueberlauf bei langen Zahlen zu vermeiden. |
| | 4 | 63 | | var rest = 0; |
| | 204 | 64 | | foreach (var c in ziffern.ToString()) |
| | 96 | 65 | | { |
| | 96 | 66 | | rest = (rest * 10 + (c - '0')) % 97; |
| | 96 | 67 | | } |
| | | 68 | | |
| | 4 | 69 | | return rest; |
| | 4 | 70 | | } |
| | | 71 | | |
| | | 72 | | /// <summary> |
| | | 73 | | /// Formatiert eine IBAN in Vierergruppen zur besseren Lesbarkeit. |
| | | 74 | | /// ABSICHTLICH NICHT GETESTET (siehe Klassenkommentar). |
| | | 75 | | /// </summary> |
| | | 76 | | public string Formatiere(string iban) |
| | 0 | 77 | | { |
| | 0 | 78 | | if (string.IsNullOrWhiteSpace(iban)) |
| | 0 | 79 | | { |
| | 0 | 80 | | return string.Empty; |
| | | 81 | | } |
| | | 82 | | |
| | 0 | 83 | | var bereinigt = iban.Replace(" ", "").ToUpperInvariant(); |
| | 0 | 84 | | var gruppen = new List<string>(); |
| | | 85 | | |
| | 0 | 86 | | for (var i = 0; i < bereinigt.Length; i += 4) |
| | 0 | 87 | | { |
| | 0 | 88 | | var laenge = Math.Min(4, bereinigt.Length - i); |
| | 0 | 89 | | gruppen.Add(bereinigt.Substring(i, laenge)); |
| | 0 | 90 | | } |
| | | 91 | | |
| | 0 | 92 | | return string.Join(" ", gruppen); |
| | 0 | 93 | | } |
| | | 94 | | } |