Grüßt euch!
Ich soll bis morgen ein Programm schreiben, welches die iBan-Prüfziffern der Länder Deutschland, Schweiz und Frankreich validiert.
Im Internet habe ich einige Lösungen gefunden, aber die alle viel zu kompliziert. Wir haben jetzt erst angefangen, unser Thema in der Vorlesung heute waren ,,while- und for-Schleifen''.
Meine Idee wäre, zuerst einmal eine elif-Verzweigung für die unterschiedlichen Länder und deren IBANs einzurichten, (Laut meiner Recherche im Netz: Deutschland: 22 Zeichen, davon 1. und 2. Zeile ,,DE‘‘, danach zwei Ziffern, dann 8 Zeilen Bankleitzahl, dann 10 Zeilen Kontonummer.
Schweiz: 21 Zeichen, davon 1. Und 2. Zeile ,,CH‘‘, danach zwei Ziffern, dann 6 Zeilen BLZ und und 11 Zeilen Kontonummer
Frankreich: 27 Zeichen, davon 1. Und 2. Zeile ,,FR‘‘, danach 5 Zeilen BLZ, 5 Zeilen Bankbereich, 11 Zeilenkontonummer und wieder zwei Ziffern
Die Prüfung der deutschen IBAN erfolgt, indem ihre ersten vier Stellen ans Ende verschoben und die Buchstaben wieder durch 1314 ersetzt werden. Diese Zahl Modulo 97 muss 1 ergeben. Dann ist die IBAN gültig.
Wie schaff ich es, die ersten vier Zeilen in die hinteren zu verschieben ? Mit append.? Das Thema Listen hatten wir noch nicht.
Mir ist klar, dass ich D den Wert 13 und E den Wert 14 zuornden muss. Aber das ist noch keine Liste.
Wäre für einen Hinweis dankbar. Entschuldigt die simple Baby-Frage, aber mir läuft nach zweitätiger Recherche in zahlreichen Internetforen die Zeit davon.
IBAN Prüfziffer validiert
Mein Versuch:
# IBAN-Nummer = DE08700901001234567890
# Wert der Buchstaben zu den Zahlen um jeweils 9 erhöhen
D = 13
E = 14
F = 15
R = 28
C = 12
H = 17
liste = ibannummer = input ('Geben Sie ihre iBan Nummer ein)
if 'DE' in ibannummer :
bankleitzahl = ibannummer[5,6,7,8,9,10,11] #bankleitzahl 70090100
kontonummer = ibannummer[12:] #kontonummer 1234567890
pruefsumme = bankleitzahl + kontonummer.append(ibannummer[0,1,2,3])
if pruefsumme % 97 = 1 :
print ('validierte IBAN')
# IBAN-Nummer = DE08700901001234567890
# Wert der Buchstaben zu den Zahlen um jeweils 9 erhöhen
D = 13
E = 14
F = 15
R = 28
C = 12
H = 17
liste = ibannummer = input ('Geben Sie ihre iBan Nummer ein)
if 'DE' in ibannummer :
bankleitzahl = ibannummer[5,6,7,8,9,10,11] #bankleitzahl 70090100
kontonummer = ibannummer[12:] #kontonummer 1234567890
pruefsumme = bankleitzahl + kontonummer.append(ibannummer[0,1,2,3])
if pruefsumme % 97 = 1 :
print ('validierte IBAN')
- __blackjack__
- User
- Beiträge: 13103
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Marceline: Das ist ja nicht einmal syntaktisch korrektes Python. Ein bisschen mehr Mühe musst Du Dir schon geben. Und einfach irgendwie etwas zusammen raten funktioniert nicht. Du musst schon eine Vorstellung davon haben was Dein Code tut.
Also erst einmal musst Du wissen was Du machen musst. Und das musst Du dann Schritt für Schritt in Code ausdrücken. Dabei musst Du wissen was der jeweilige Code machen soll und was er tatsächlich macht. Das kannst Du zum Beispiel über `print()`-Ausgaben überprüfen. Und wenn die Ausgabe dann nicht mit dem übereinstimmt was Du ja sicher irgendwo mit Papier und Stift mal an Beispielen durchprobiert hast, dann ist der Code an der Stelle falsch. *Dann* kannst Du mit dem konkreten Problem und lauffähigem Code hier fragen.
Also erst einmal musst Du wissen was Du machen musst. Und das musst Du dann Schritt für Schritt in Code ausdrücken. Dabei musst Du wissen was der jeweilige Code machen soll und was er tatsächlich macht. Das kannst Du zum Beispiel über `print()`-Ausgaben überprüfen. Und wenn die Ausgabe dann nicht mit dem übereinstimmt was Du ja sicher irgendwo mit Papier und Stift mal an Beispielen durchprobiert hast, dann ist der Code an der Stelle falsch. *Dann* kannst Du mit dem konkreten Problem und lauffähigem Code hier fragen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ok, ich habe es jetzt für Deutschland hinekriegt. Jetzt muss ich es noch für Schweizerische und Französische IBANs machen. Das Problem ist, dass dort, im Gegensatz zu Deutschland, auch Buchstaben in der Kontonummer enthalten sind. Ich will es jetzt so machen, dass z.B. A immer den Wert 10 hat, B immer 11, C = 12, D = 13...., Z = 35. Arbeitet man dann mit def oder mit einer Liste?
Code: Alles auswählen
if 'CH' in ibannummer: #wennn IBAN Nummer Schweizerisch
#Beispiel Schweiz: CH100023000A109822346
bankleitzahl = ibannummer [4:9] #Bankleitzahl 00230
kontonummer = ibannummer[9:] #00A109822346
#das A durch 10 ersetzen
def A():
A = 10
print (kontonummer)
Lies dir doch diese Beschreibung der Validierung noch mal durch.
https://de.wikipedia.org/wiki/Internati ... ontonummer
Dafür brauch man keine Listen, Schleifen etc.
https://de.wikipedia.org/wiki/Internati ... ontonummer
Die Umwandlung der IBAN kann durch einfache Stringoperationen erfolgen, das Ergebnis in eine Ganzzahl umwandeln und dann Modulus 97 berechnen.Validierung
Im Rahmen von IPI und ECBS wurde das Prüfziffernverfahren auf den Standard ISO 7064 mod 97-10 festgelegt und von den nationalen Normungsgremien der Banken übernommen.[26] Die Prüfsumme liegt im Bereich „02“ bis „98“, durch abweichende Berechnungsmethoden bei verschiedenen Finanzinstituten kamen aber auch „00“, „01“ und „99“ vor. Die Korrekturen sind weitgehend abgeschlossen. Jedoch kann nicht ausgeschlossen werden, dass weiterhin IBANs mit „falschen“ Prüfziffern existieren.
Zur Validierung der Prüfsumme wird zunächst eine Zahl erstellt:
Diese setzt sich aus BBAN (in Deutschland z. B. 18 Stellen) + Länderkürzel kodiert + Prüfsumme zusammen. Dabei werden die beiden Buchstaben des Länderkürzels sowie weitere etwa in der Kontonummer enthaltene Buchstaben durch ihre Position im lateinischen Alphabet + 9 ersetzt (A = 10, B = 11, …, Z = 35).
Nun wird der Rest berechnet, der sich beim ganzzahligen Teilen der Zahl durch 97 ergibt (Modulo 97).
Das Ergebnis muss 1 sein, ansonsten ist die IBAN falsch.
Beispiel:
1 IBAN DE68 2105 0170 0012 3456 78
2 Umstellung 2105 0170 0012 3456 78DE 68
3 Modulo 210501700012345678131468 mod 97 = 1
Dafür brauch man keine Listen, Schleifen etc.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Strings haben in Python eine "startswith()' Methode. Damit lässt sich dein Problem lösen, ohne das du irgendwelche komischen Substitutionen machen musst.
Plan B: du weißt, dass der IBAN immer mit der 2-stelligen Länderkennung, beginnt. Slicing kennst du auch, verwendest du ja im zuletzt gezeigten Code. Also kannst du auch die ersten beiden Stellen aus dem IBAN extrahieren und dann den Vergleich gegen DE, FR, CH, ... machen.
Gruß, noisefloor
Strings haben in Python eine "startswith()' Methode. Damit lässt sich dein Problem lösen, ohne das du irgendwelche komischen Substitutionen machen musst.
Plan B: du weißt, dass der IBAN immer mit der 2-stelligen Länderkennung, beginnt. Slicing kennst du auch, verwendest du ja im zuletzt gezeigten Code. Also kannst du auch die ersten beiden Stellen aus dem IBAN extrahieren und dann den Vergleich gegen DE, FR, CH, ... machen.
Gruß, noisefloor
Danke für die Antwort. Vielleicht zeig ich der Vollständigkeit halber meinen ganzen Code.
Wie gesagt, für Deutschland funktioniert es einwandfrei. Bei schweizerischen und französischen IBANS stoße ich auf das Problem, dass der Interpreter merkt, weil in der letzten Zeile beim Integer für die Prüfungssumme einen Buchstaben (in meinem Beispiel das ,A') enthält und denn will ich halt raus kriegen, bzw. in A = 10 umwandeln.
startswith() hab ich probiert, kommt aber nur unsinn raus. Ist die IBAN-Nr. überhaupt ein String? Es gibt mir wirklich nur darum, die Buchstaben A = 10, B = 11,...Z = 35 zuzuordnen? Auch mit ''=='' und ''is'' komme ich leider nicht weiter
Code: Alles auswählen
#Beispiel-IBAN Nummer: DE08700901001234567890
ibannummer = input ('Geben Sie ihre iBan Nummer ein: ')
if 'DE' in ibannummer: #wennn IBAN Nummer deutsch
bankleitzahl = ibannummer [4:12] #Bankleitzahl 70090100
kontonummer = ibannummer[12:] #Kontonummer 1234567890
bban = bankleitzahl + kontonummer #BBAN 700901001234567890
landererkennung = '1314'
landererkennung_ergaenzt= '131400' #Ländererkennung mit 00 ergänzt
pruefungssumme = bban + landererkennung_ergaenzt #Prüfsumme
pruefungssumme_modulo = int(pruefungssumme) % 97 #Prüfsumme Modulo 97
pruefungsziffer = 98 - pruefungssumme_modulo
if pruefungsziffer > 9:
pruefungsziffer = 98 - pruefungssumme_modulo
else:
pruefungsziffer = 98 - pruefungssumme_modulo
pruefungsziffer = str(pruefungsziffer).zfill(2)
#wenn (98 - Prüfungssumme) < 9 füge ergänze eine führende Null (08)
print ('Ihre Pruefziffer lautet', pruefungsziffer)
#Prüfungsziffer rausgeben
pruefung = bban + landererkennung + pruefungsziffer
if int(pruefung) % 97 == 1 : #Validieren
print ('Sie haben eine gültige deutsche IBAN-Nummer')
elif 'CH' in ibannummer: #wennn IBAN Nummer Schweizerisch
#Beispiel Schweiz: CH100023000A109822346
bankleitzahl = ibannummer [4:9] #Bankleitzahl 00230
kontonummer = ibannummer[9:] #00A109822346
bban = bankleitzahl + kontonummer #BBAN
landererkennung = '1217'
landererkennung_ergaenzt= '121700' #Ländererkennung mit 00 ergänzt
pruefungssumme = bban + landererkennung_ergaenzt #Prüfsumme
print (pruefungssumme)
pruefungssumme_modulo = int(pruefungssumme) % 97 #Prüfsumme Modulo 97
startswith() hab ich probiert, kommt aber nur unsinn raus. Ist die IBAN-Nr. überhaupt ein String? Es gibt mir wirklich nur darum, die Buchstaben A = 10, B = 11,...Z = 35 zuzuordnen? Auch mit ''=='' und ''is'' komme ich leider nicht weiter
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Gruß, noisefloor
Dann zeig' mal, was du gemacht hast. Das wird nämlich funktionieren, wenn man es korrekt angehtstartswith() hab ich probiert, kommt aber nur unsinn raus.
Alles, was du über `input` einliest, ist erst mal ein String in Python.Ist die IBAN-Nr. überhaupt ein String?
Gruß, noisefloor
Verstehe gerade nicht die Funktion von startswith. (Das hatten wir noch nicht). Man dann damit überprüfen, mit welcher Länderkennzeichnung die IBAN startet, z.b.
ibannummer.startswith('CH')
print ('True')
,aber hilft mir das weiter, die Zahlen umzuschreiben?
ibannummer.startswith('CH')
print ('True')
,aber hilft mir das weiter, die Zahlen umzuschreiben?
Code: Alles auswählen
dict = {'a':'10','b':'11','c':'12','d':'13','e':'14','f':'15','g':'16','h':'17',
'i':'18','j':'19','k':'20','l':'21','m':'22','n':'23','o':'24','p':'25','q':'26',
'r':'27','s':'28','t':'29','u':'30','v':'31','w':'32','x':'33','y':'34','z':'35'
}
print (kontonummer)
- __blackjack__
- User
- Beiträge: 13103
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Marceline: Ich verstehe ja nicht warum Du für verschiedene Länder verschiedene Prüfungen machen willst. Das *erstellen* von IBANs aus Kontonummer und Bankleitzahl ist länderspezifisch, die Prüfung sollte allgemein möglich sein. Dein Code macht da auch viel zu viel, weil man zum prüfen gar nicht wissen muss wie sich die IBAN auf Kontonummer und Bankleitzahl aufteilt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Er muss die Buchstaben nicht in Zahlen umwandeln, sondern in Strings
Code: Alles auswählen
IBAN = 'DE68210501700012345678'
ersetzt = IBAN.replace('DE', '1314')
if int(f'{ersetzt[6:]}{ersetzt[:6]}') % 97 == 1:
print('IBAN korrekt')
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Gruß, noisefloor
Die `startswith()` Methode hat einen Rückgabewert, nämlich `True` oder `False`, damit musst du arbeiten. In deinem Beispiel wertest du den Rückgabewert nicht aus, von daher wird `print('True'') immer ausgegeben. Beispiel für `startswith`:
Code: Alles auswählen
>>> iban = 'DE08700901001234567890'
>>> if iban.startswith('CH'):
... print('Schweizer IBAN')
... elif iban.startswith('DE'):
... print('Deutscher IBAN')
... else:
... print('Weder deutscher noch schweizer IBAN')
...
Deutscher IBAN
>>>
ok, dann habe ich für dich mal weitergedacht und der TS freut sich
Code: Alles auswählen
tabelle = {}
for zahl in range(10):
tabelle[str(zahl)] = str(zahl)
for letter in range(65, 91):
tabelle[chr(letter)] = str(letter-55)
IBANS = ('DE68210501700012345678', 'AT611904300234573201', 'CH78005540A1024502601')
for iban in IBANS:
ersetzt = ''
for zeichen in iban:
ersetzt = f'{ersetzt}{tabelle[zeichen]}'
if int(f'{ersetzt[6:]}{ersetzt[:6]}') % 97 == 1:
print('IBAN korrekt')
IBAN korrekt
IBAN korrekt
IBAN korrekt
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
- __blackjack__
- User
- Beiträge: 13103
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Ich habe das spasseshalber mal in Vala gelöst:
Code: Alles auswählen
using GLib;
using Gmp;
static int main (string[] args)
{
if (args.length == 1) {
stdout.puts ("Usage: check_iban IBAN\n");
return 1;
}
string iban = args[1];
if (! iban.is_ascii ()) {
stdout.puts ("IBAN must be ASCII only.\n");
return 2;
}
if (iban.length < 4) {
stdout.puts ("IBAN is too short.\n");
return 2;
}
string rearranged = iban.substring (4).concat (iban.substring (0, 4));
StringBuilder characters_replaced_by_digits =
new StringBuilder.sized (iban.length + 2);
for (int i = 0; i < rearranged.length; ++i) {
char c = rearranged[i];
if (c.isalpha ()) {
characters_replaced_by_digits
.append (((uint8) (c.toupper () - 'A' + 10)).to_string ());
} else if (c.isdigit ()) {
characters_replaced_by_digits.append_c (c);
} else {
stdout.printf ("Unexpected character '%c' in IBAN.\n", c);
return 2;
}
}
Integer number =
Integer.init_set_str (characters_replaced_by_digits.str, 10);
bool is_valid = Integer.fdiv_ui (number, 97) == 1;
stdout.printf ("The IBAN %s is %s.\n",
iban, (is_valid) ? "valid" : "invalid");
return (is_valid) ? 0 : 3;
}
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@ThomasL: das iterative Stringzusammensetzen ist ja noch schlimmer als das übliche `ersetzt += tabelle[zeichen]`, denn da hat der Interpreter wirklich keine Chance mehr, das zu optimieren.
Da Du schon eine Lösung gepostet hast, hier die zwei-Zeilen-Lösung:
Da Du schon eine Lösung gepostet hast, hier die zwei-Zeilen-Lösung:
Code: Alles auswählen
IBANS = ['DE68210501700012345678', 'AT611904300234573201', 'CH78005540A1024502601']
for iban in IBANS:
ersetzt = ''.join(str(int(c, 36)) for c in iban[4:] + iban[:4])
print('{} {}korrekt'.format(iban,
"" if int(ersetzt) % 97 == 1 else "nicht "))
Schmunzel, und da dachte ich mir doch glatt das wäre besonders elegant
Aber ich bin jederzeit bereit zu lernen und jetzt habe ich für solche Fälle ein neues Snippet in meiner Sammlung. Danke
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png