Last active
April 27, 2021 10:11
-
-
Save dronir/00ee87a54fd3316d7fca13d43cc3ffca to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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