Functional Weave
Code in Python

validation.uk-sort-code-account@3.0.0

vectors.json

28,076 bytes · view raw

[
  {"name": "MOD10 passes: 7+2+9+28+5+18+49+2 = 120", "args": ["115000", "12345672", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "115000", "accountNumber": "12345672", "checked": true, "reason": null}},
  {"name": "MOD10 fails: 7+2+9+28+5+18+49+8 = 126", "args": ["115000", "12345678", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "MOD11 passes: 8+14+18+20+20+18+14+9 = 121 = 11 x 11", "args": ["120000", "12345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "120000", "accountNumber": "12345679", "checked": true, "reason": null}},
  {"name": "MOD11 fails: the total is 120, remainder 10", "args": ["120000", "12345678", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "DBLAL adds the digits of each product (18 counts 9, 14 counts 5, 10 counts 1): 50 passes, where adding the products whole gives 77", "args": ["130000", "98765436", {"rows": [{"start": "130000", "end": "139999", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "130000", "accountNumber": "98765436", "checked": true, "reason": null}},
  {"name": "DBLAL: one more in h makes 51, which fails", "args": ["130000", "98765437", {"rows": [{"start": "130000", "end": "139999", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "two rows: MOD11 (99) and DBLAL (40) both pass", "args": ["141414", "12345601", {"rows": [{"start": "140000", "end": "149999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}, {"start": "140000", "end": "149999", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "141414", "accountNumber": "12345601", "checked": true, "reason": null}},
  {"name": "two rows: MOD11 passes (110) but DBLAL fails (51), so invalid", "args": ["141414", "12345628", {"rows": [{"start": "140000", "end": "149999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}, {"start": "140000", "end": "149999", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "two rows: MOD11 fails but DBLAL passes, so invalid", "args": ["141414", "12345619", {"rows": [{"start": "140000", "end": "149999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}, {"start": "140000", "end": "149999", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "the first sort code of a range is in it", "args": ["110000", "12345672", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}, {"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "110000", "accountNumber": "12345672", "checked": true, "reason": null}},
  {"name": "the last sort code of a range is in it", "args": ["119999", "12345672", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}, {"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "119999", "accountNumber": "12345672", "checked": true, "reason": null}},
  {"name": "a sort code between rows is in none: presumed valid, reported unchecked", "args": ["109999", "12345678", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}, {"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "109999", "accountNumber": "12345678", "checked": false, "reason": null}},
  {"name": "an empty table checks nothing: every well-formed pair is unchecked", "args": ["089999", "66374958", {"rows": [], "substitutions": []}], "expect": {"valid": true, "sortCode": "089999", "accountNumber": "66374958", "checked": false, "reason": null}},
  {"name": "a negative weight in a MOD11 row: -9+14+18+20+20+18+0+7 = 88", "args": ["330000", "92345607", {"rows": [{"start": "330000", "end": "330099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, -1, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "330000", "accountNumber": "92345607", "checked": true, "reason": null}},
  {"name": "exception 1: 27 is added to the DBLAL total, 33 + 27 = 60", "args": ["210050", "12345606", {"rows": [{"start": "210000", "end": "210099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 1}], "substitutions": []}], "expect": {"valid": true, "sortCode": "210050", "accountNumber": "12345606", "checked": true, "reason": null}},
  {"name": "exception 1: 34 + 27 = 61 fails", "args": ["210050", "12345607", {"rows": [{"start": "210000", "end": "210099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 1}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 2 & 9: a is 0, so the row's own weights are used and pass", "args": ["220010", "02345604", {"rows": [{"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 1], "exception": 2}, {"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 9}], "substitutions": []}], "expect": {"valid": true, "sortCode": "220010", "accountNumber": "02345604", "checked": true, "reason": null}},
  {"name": "exception 2: a is not 0 and g is not 9, so the weights become 0 0 1 2 5 3 6 4 8 7 10 9 3 1 (176)", "args": ["220010", "12345601", {"rows": [{"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 1], "exception": 2}, {"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 9}], "substitutions": []}], "expect": {"valid": true, "sortCode": "220010", "accountNumber": "12345601", "checked": true, "reason": null}},
  {"name": "exception 2: a is not 0 and g is 9, so the weights become 0 0 0 0 0 0 0 0 8 7 10 9 3 1", "args": ["220010", "12345694", {"rows": [{"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 1], "exception": 2}, {"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 9}], "substitutions": []}], "expect": {"valid": true, "sortCode": "220010", "accountNumber": "12345694", "checked": true, "reason": null}},
  {"name": "exception 2 fails, and exception 9 passes only because sort code 309634 replaces 220010", "args": ["220010", "12345615", {"rows": [{"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 1], "exception": 2}, {"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 9}], "substitutions": []}], "expect": {"valid": true, "sortCode": "220010", "accountNumber": "12345615", "checked": true, "reason": null}},
  {"name": "exception 2 and exception 9 both fail", "args": ["220010", "12345600", {"rows": [{"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 1], "exception": 2}, {"start": "220000", "end": "220099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 9}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 3: c is 6, so the failing DBLAL check is skipped", "args": ["230020", "12645602", {"rows": [{"start": "230000", "end": "230099", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}, {"start": "230000", "end": "230099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 3}], "substitutions": []}], "expect": {"valid": true, "sortCode": "230020", "accountNumber": "12645602", "checked": true, "reason": null}},
  {"name": "exception 3: c is 1, so the DBLAL check runs and fails", "args": ["230020", "12145607", {"rows": [{"start": "230000", "end": "230099", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}, {"start": "230000", "end": "230099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 3}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 4: the remainder, 98 mod 11 = 10, equals gh", "args": ["240030", "12345610", {"rows": [{"start": "240000", "end": "240099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 0, 0], "exception": 4}], "substitutions": []}], "expect": {"valid": true, "sortCode": "240030", "accountNumber": "12345610", "checked": true, "reason": null}},
  {"name": "exception 4: the remainder 10 does not equal gh = 11", "args": ["240030", "12345611", {"rows": [{"start": "240000", "end": "240099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 0, 0], "exception": 4}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 5 with substitution: 250050 is weighted as 250010; MOD11 124 gives g = 11 - 3 = 8, DBLAL 39 gives h = 10 - 9 = 1", "args": ["250050", "12345681", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": [{"original": "250050", "substitute": "250010"}]}], "expect": {"valid": true, "sortCode": "250050", "accountNumber": "12345681", "checked": true, "reason": null}},
  {"name": "exception 5 without the substitution the same account fails", "args": ["250050", "12345681", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 5, a sort code with no substitute: both check digits right", "args": ["250020", "12345655", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": [{"original": "250050", "substitute": "250010"}]}], "expect": {"valid": true, "sortCode": "250020", "accountNumber": "12345655", "checked": true, "reason": null}},
  {"name": "exception 5: a MOD11 remainder of 1 is always invalid", "args": ["250020", "12345903", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": [{"original": "250050", "substitute": "250010"}]}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 5: a MOD11 remainder of 0 needs g = 0", "args": ["250020", "12346703", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": [{"original": "250050", "substitute": "250010"}]}], "expect": {"valid": true, "sortCode": "250020", "accountNumber": "12346703", "checked": true, "reason": null}},
  {"name": "exception 5: g right, h wrong", "args": ["250020", "12345650", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": [{"original": "250050", "substitute": "250010"}]}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 6: a is 5 and g equals h, a foreign currency account: valid but unchecked", "args": ["260060", "52345600", {"rows": [{"start": "260000", "end": "260099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 6}, {"start": "260000", "end": "260099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 6}], "substitutions": []}], "expect": {"valid": true, "sortCode": "260060", "accountNumber": "52345600", "checked": false, "reason": null}},
  {"name": "exception 6: a is 5 but g differs from h, so it is checked and fails", "args": ["260060", "52345601", {"rows": [{"start": "260000", "end": "260099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 6}, {"start": "260000", "end": "260099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 6}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 6: a is 3, so it is checked and fails", "args": ["260060", "32345600", {"rows": [{"start": "260000", "end": "260099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 6}, {"start": "260000", "end": "260099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "exception": 6}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 7: g is 9, so weights u to b are zeroed and it passes", "args": ["270070", "12345690", {"rows": [{"start": "270000", "end": "270099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 7}], "substitutions": []}], "expect": {"valid": true, "sortCode": "270070", "accountNumber": "12345690", "checked": true, "reason": null}},
  {"name": "exception 7: g is not 9, the ordinary check passes", "args": ["270070", "12345613", {"rows": [{"start": "270000", "end": "270099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 7}], "substitutions": []}], "expect": {"valid": true, "sortCode": "270070", "accountNumber": "12345613", "checked": true, "reason": null}},
  {"name": "exception 8: checked as sort code 090126, 58 + 107 = 165", "args": ["280080", "12345603", {"rows": [{"start": "280000", "end": "280099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 8}], "substitutions": []}], "expect": {"valid": true, "sortCode": "280080", "accountNumber": "12345603", "checked": true, "reason": null}},
  {"name": "exception 8: two more in h makes 167, which fails", "args": ["280080", "12345604", {"rows": [{"start": "280000", "end": "280099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 8}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 10 & 11: the first fails, the second passes, either is enough", "args": ["300030", "12345601", {"rows": [{"start": "300000", "end": "300099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 10}, {"start": "300000", "end": "300099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 11}], "substitutions": []}], "expect": {"valid": true, "sortCode": "300030", "accountNumber": "12345601", "checked": true, "reason": null}},
  {"name": "exception 10: ab is 99 and g is 9, so weights u to b are zeroed (121) and it passes", "args": ["300030", "99345690", {"rows": [{"start": "300000", "end": "300099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 10}, {"start": "300000", "end": "300099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 11}], "substitutions": []}], "expect": {"valid": true, "sortCode": "300030", "accountNumber": "99345690", "checked": true, "reason": null}},
  {"name": "exception 10: ab is 09 and g is 9, the same", "args": ["300030", "09345690", {"rows": [{"start": "300000", "end": "300099", "algorithm": "MOD11", "weights": [3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2], "exception": 10}, {"start": "300000", "end": "300099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 11}], "substitutions": []}], "expect": {"valid": true, "sortCode": "300030", "accountNumber": "09345690", "checked": true, "reason": null}},
  {"name": "exception 12 & 13: MOD11 fails, MOD10 passes, either is enough", "args": ["310010", "12345614", {"rows": [{"start": "310000", "end": "310099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 12}, {"start": "310000", "end": "310099", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": 13}], "substitutions": []}], "expect": {"valid": true, "sortCode": "310010", "accountNumber": "12345614", "checked": true, "reason": null}},
  {"name": "exception 12 & 13: both fail", "args": ["310010", "12345600", {"rows": [{"start": "310000", "end": "310099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 12}, {"start": "310000", "end": "310099", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": 13}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "exception 14: fails (107), h is 9, so 01234560 is checked instead (77) and passes", "args": ["320040", "12345609", {"rows": [{"start": "320000", "end": "320099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 14}], "substitutions": []}], "expect": {"valid": true, "sortCode": "320040", "accountNumber": "12345609", "checked": true, "reason": null}},
  {"name": "exception 14: h is 0, the same retry passes", "args": ["320040", "12345600", {"rows": [{"start": "320000", "end": "320099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 14}], "substitutions": []}], "expect": {"valid": true, "sortCode": "320040", "accountNumber": "12345600", "checked": true, "reason": null}},
  {"name": "exception 14: h is 2, so there is no retry even though the shifted number would pass", "args": ["320040", "12345602", {"rows": [{"start": "320000", "end": "320099", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 14}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": true, "reason": "bad-check-digit"}},
  {"name": "a sort code with hyphens and an account number with a space", "args": ["11-50-00", "1234 5672", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "115000", "accountNumber": "12345672", "checked": true, "reason": null}},
  {"name": "a seven-digit account number gets one leading zero: 0+7+12+15+16+15+12+0 = 77", "args": ["120000", "1234560", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "120000", "accountNumber": "01234560", "checked": true, "reason": null}},
  {"name": "a six-digit account number gets two leading zeros: 0+0+18+20+20+18+14+9 = 99", "args": ["120000", "345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": true, "sortCode": "120000", "accountNumber": "00345679", "checked": true, "reason": null}},
  {"name": "nine digits needs the bank's own standardisation first", "args": ["120000", "123456789", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "non-standard-account"}},
  {"name": "ten digits too", "args": ["120000", "0123456789", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "non-standard-account"}},
  {"name": "five digits is too short to be any account number", "args": ["120000", "12345", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "bad-account-number"}},
  {"name": "a letter in the account number", "args": ["120000", "1234567O", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "bad-account-number"}},
  {"name": "non-ASCII digits in the account number", "args": ["120000", "1234567٩", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "bad-account-number"}},
  {"name": "a five-digit sort code", "args": ["12000", "12345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "bad-sort-code"}},
  {"name": "both empty reports the sort code first", "args": ["", "", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "bad-sort-code"}},
  {"name": "a dot is not a sort code separator", "args": ["12.00.00", "12345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expect": {"valid": false, "sortCode": null, "accountNumber": null, "checked": false, "reason": "bad-sort-code"}},
  {"name": "a row with 13 weights", "args": ["120000", "12345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2], "exception": null}], "substitutions": []}], "expectError": "modulus table row 1: expected 14 weights, found 13"},
  {"name": "an unknown algorithm", "args": ["120000", "12345679", {"rows": [{"start": "110000", "end": "119999", "algorithm": "MOD10", "weights": [0, 0, 0, 0, 0, 0, 7, 1, 3, 7, 1, 3, 7, 1], "exception": null}, {"start": "120000", "end": "129999", "algorithm": "MOD12", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expectError": "modulus table row 2: unknown algorithm \"MOD12\""},
  {"name": "a five-digit range start", "args": ["120000", "12345679", {"rows": [{"start": "12000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": null}], "substitutions": []}], "expectError": "modulus table row 1: start and end must be six-digit sort codes"},
  {"name": "a negative weight in a DBLAL row", "args": ["130000", "12345679", {"rows": [{"start": "130000", "end": "139999", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, -1, 2, 1, 2, 1, 2, 1], "exception": null}], "substitutions": []}], "expectError": "modulus table row 1: a DBLAL row cannot have a negative weight"},
  {"name": "exception 15 does not exist", "args": ["120000", "12345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 15}], "substitutions": []}], "expectError": "modulus table row 1: exception must be from 1 to 14"},
  {"name": "a malformed table is an error even for a sort code it does not cover", "args": ["990000", "12345679", {"rows": [{"start": "120000", "end": "129999", "algorithm": "MOD11", "weights": [0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1], "exception": 0}], "substitutions": []}], "expectError": "modulus table row 1: exception must be from 1 to 14"},
  {"name": "a substitution with a short sort code", "args": ["250020", "12345655", {"rows": [{"start": "250000", "end": "250099", "algorithm": "MOD11", "weights": [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2, 0, 0], "exception": 5}, {"start": "250000", "end": "250099", "algorithm": "DBLAL", "weights": [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0], "exception": 5}], "substitutions": [{"original": "25005", "substitute": "250010"}]}], "expectError": "modulus table substitution 1: original and substitute must be six-digit sort codes"}
]