De meeste bankkaarten hebben een uniek nummer waarvan de geldigheid kan gecontroleerd worden aan de hand van een algoritme dat ontwikkeld werd door Hans Peter Luhn van IBM. Dit algoritme kan bijna alle fouten opsporen die het resultaat zijn van één verkeerd ingegeven cijfer, de omwisseling van twee opeenvolgende cijfers, en tal van andere fouten. IBM nam in 1954 een patent op het algoritme (U.S. Patent 29500481), maar nu mag het door iedereen vrij gebruikt worden.
Het algoritme van Luhn werkt van rechts naar links, waarbij het cijfer helemaal achteraan een controlecijfer is. Het controlecijfer moet de volgende test doorstaan.
Startend vanaf het cijfer dat links van het controlecijfer staat, schuiven we telkens twee cijfers op naar links. We verdubbelen telkens de waarde van elk van deze cijfers. Als deze verdubbeling resulteert in een getal van twee cijfers, dan tellen we de cijfers van dit getal bij elkaar op. Op die manier wordt het cijfer 7 bijvoorbeeld verdubbeld tot 14, waarna de som van de cijfers gelijk is aan 5.
Daarna nemen we de som van de cijfers van het kaartnummer, inclusief het controlecijfer.
Als de totale som deelbaar is door tien, dan is kaartnummer geldig. Anders is het kaartnummer ongeldig.
Volgens dit algoritme is het kaartnummer 49927398716 dus geldig. De som wordt immers als volgt berekend \[ 6 + (2) + 7 + (1 + 6) + 9 + (6) + 7 + (4) + 9 + (1 + 8) + 4 = 70 \] en dat resultaat is deelbaar door 10. Hierbij wordt de som van de cijfers na de verdubbeling aangegeven tussen ronde haakjes.
Je opdracht bestaat erin om de volgende drie functies te schrijven, waarbij telkens een kaartnummer als string aan de functie moet doorgegeven worden.
Een functie luhn die de som van de cijfers van het kaartnummer teruggeeft, zoals die wordt berekend volgens het algoritme van Luhn.
Een functie geldig die aangeeft of het gegeven kaartnummer al of niet geldig is volgens het algoritme van Luhn.
Een functie controle die het gegeven kaartnummer aanvult met een controlecijfer, zodat het een geldig kaartnummer wordt volgens het algoritme van Luhn.
Zorg er bij de implementatie van deze functies voor dat je zo optimaal mogelijk hergebruik maakt van je broncode.
>>> luhn('49927398716')
70
>>> luhn('49927938716')
67
>>> luhn('79927398716')
73
"""
>>> geldig('49927398716')
True
>>> geldig('49927938716')
False
>>> geldig('79927398716')
False
>>> controle('4992739871')
'49927398716'
>>> controle('4992793871')
'49927938719'
>>> controle('7992739871')
'79927398713'