Skip to content

Instantly share code, notes, and snippets.

@dronir
Last active April 27, 2021 10:11
Show Gist options
  • Select an option

  • Save dronir/00ee87a54fd3316d7fca13d43cc3ffca to your computer and use it in GitHub Desktop.

Select an option

Save dronir/00ee87a54fd3316d7fca13d43cc3ffca to your computer and use it in GitHub Desktop.
# Calculate Finnish bank reference numbers
# The reference is computed by:
#
# 1. Add together the digits of the number from right to left,
# multiplied cyclically by the weights 7, 3, and 1.
# E.g. for 1234, the total is 7*4 + 3*3 + 1*2 + 7*1 == 46.
#
# 2. Subtract the total from the next highest multiple of ten.
# For the number 1234, this is 50-46 == 4.
# This is the negative of the total, modulo ten: -46 % 10 == 4
#
# 3. Append the checksum to the original number.
# For 1234, you get 12344.
#
# Note: the input number should be at least 3 digits.
def weight(i):
"""Return digit weights 7, 3, 1, repeating."""
return 2**(3-(i%3)) - 1
def checksum(N):
"""Compute the checksum for number N."""
S = sum(weight(i) * int(digit) for (i, digit) in enumerate(reversed(str(N))))
return -S % 10
def reference(N):
"""Given a number, compute the checksum and append to the number."""
return 10*N + checksum(N)
def verify_reference(N):
"""Verify that a reference number is correct."""
last_digit = N % 10
body = (N - last_digit) // 10
return checksum(body) == last_digit
def test_weights():
"""Test that the weights get computed correctly."""
assert weight(0) == 7
assert weight(1) == 3
assert weight(2) == 1
assert weight(3) == 7
assert weight(4) == 3
assert weight(5) == 1
def test_checksum():
"""Test the checksum computation."""
assert checksum(123) == 2
assert checksum(1234) == 4
assert checksum(1000) == 3
assert checksum(10000) == 7
assert checksum(100000) == 9
assert checksum(3141592) == 3
def test_ref():
"""Test that the output is correct for some test cases (verified elsewhere)."""
assert reference(123) == 1232
assert reference(1234) == 12344
assert reference(10000) == 100007
assert reference(1000) == 10003
assert reference(3141592) == 31415923
assert reference(1002021) == 10020216
def test_verify():
"""Test that the verification function works for some examples."""
assert verify_reference(12344)
assert not verify_reference(12340)
assert not verify_reference(12341)
assert not verify_reference(12342)
assert not verify_reference(12343)
assert not verify_reference(12345)
assert not verify_reference(12346)
assert not verify_reference(12347)
assert not verify_reference(12348)
assert not verify_reference(12349)
assert verify_reference(100007)
assert not verify_reference(100000)
assert not verify_reference(100001)
assert not verify_reference(100002)
assert not verify_reference(100003)
assert not verify_reference(100004)
assert not verify_reference(100005)
assert not verify_reference(100006)
assert not verify_reference(100008)
assert not verify_reference(100009)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment