ibantools 4.1.0 → 4.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ChangeLog CHANGED
@@ -1,3 +1,35 @@
1
+ 2022-02-03 Saša Jovanić <sasa@simplify.ba>
2
+ * Version 4.1.4
3
+ * Fix issue #103 - Remove Dutch BBAN validation
4
+ * Various development dependencies upgrades
5
+
6
+ 2021-12-17 Saša Jovanić <sasa@simplify.ba>
7
+ * Version 4.1.3
8
+ * Fix issue #85 - Fix NaN issue when calling `validateIBAN`
9
+
10
+ 2021-12-14 Saša Jovanić <sasa@simplify.ba>
11
+ * Version 4.1.2
12
+ * Fix issue #83 - Fix problem when country can not be found when calling `validateIBAN`
13
+
14
+ 2021-12-05 Saša Jovanić <sasa@simplify.ba>
15
+ * Version 4.1.1
16
+ * Added Hungarian (HU) BBAN validation
17
+
18
+ 2021-12-01 Saša Jovanić <sasa@simplify.ba>
19
+ * Improve test coverage
20
+
21
+ 2021-11-30 Saša Jovanić <sasa@simplify.ba>
22
+ * Added Estonian (EE) BBAN validation
23
+ * Added Finland (FI) BBAN validation
24
+ * Aland Islands (AX) uses BBAN valkidation from Finland
25
+ * Added French (FR) and Monaco (MC) BBAN validation
26
+
27
+ 2021-11-28 Saša Jovanić <sasa@simplify.ba>
28
+ * Added Czech (CZ) BBAN validation
29
+
30
+ 2021-11-27 Saša Jovanić <sasa@simplify.ba>
31
+ * Added Croatian (HR) BBAN validation
32
+
1
33
  2021-11-25 Saša Jovanić <sasa@simplify.ba>
2
34
  * Version 4.1.0
3
35
  * Added Belgian (BE) extra BBAN validation
@@ -8,7 +8,7 @@
8
8
  * @package Documentation
9
9
  * @author Saša Jovanić
10
10
  * @module ibantools
11
- * @version 4.1.0
11
+ * @version 4.1.4
12
12
  * @license MPL-2.0
13
13
  * @preferred
14
14
  */
@@ -71,6 +71,7 @@ function validateIBAN(iban) {
71
71
  if (!spec || !(spec.bban_regexp || spec.chars)) {
72
72
  result.valid = false;
73
73
  result.errorCodes.push(ValidationErrorsIBAN.NoIBANCountry);
74
+ return result;
74
75
  }
75
76
  if (spec && spec.chars && spec.chars !== iban.length) {
76
77
  result.valid = false;
@@ -433,36 +434,14 @@ exports.extractBIC = extractBIC;
433
434
  var checkNorwayBBAN = function (bban) {
434
435
  var weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
435
436
  var bbanWithoutSpacesAndPeriods = bban.replace(/[\s.]+/g, '');
436
- if (bbanWithoutSpacesAndPeriods.length !== 11) {
437
- return false;
438
- }
439
- else {
440
- var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);
441
- var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);
442
- var sum = 0;
443
- for (var index = 0; index < 10; index++) {
444
- sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];
445
- }
446
- var remainder = sum % 11;
447
- return controlDigit === (remainder === 0 ? 0 : 11 - remainder);
448
- }
449
- };
450
- /**
451
- * Used for Netherlands BBAN check
452
- *
453
- * @ignore
454
- */
455
- var checkDutchBBAN = function (bban) {
456
- var bbanWithoutSpacesAndPeriods = bban.replace(/[\s.]+/g, '');
457
- var accountNumber = bbanWithoutSpacesAndPeriods.substring(4, 14);
458
- if (accountNumber.startsWith('000')) {
459
- return true; // Postbank account, no `elfproef` possible
460
- }
437
+ var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);
438
+ var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);
461
439
  var sum = 0;
462
440
  for (var index = 0; index < 10; index++) {
463
- sum += parseInt(accountNumber.charAt(index), 10) * (10 - index);
441
+ sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];
464
442
  }
465
- return sum % 11 === 0;
443
+ var remainder = sum % 11;
444
+ return controlDigit === (remainder === 0 ? 0 : 11 - remainder);
466
445
  };
467
446
  /**
468
447
  * Used for Belgian BBAN check
@@ -473,11 +452,8 @@ var checkBelgianBBAN = function (bban) {
473
452
  var stripped = bban.replace(/[\s.]+/g, '');
474
453
  var checkingPart = parseInt(stripped.substring(0, stripped.length - 2), 10);
475
454
  var checksum = parseInt(stripped.substring(stripped.length - 2, stripped.length), 10);
476
- var reminder = checkingPart % 97;
477
- if (reminder === 0) {
478
- reminder = 97;
479
- }
480
- return reminder === checksum;
455
+ var remainder = checkingPart % 97 === 0 ? 97 : checkingPart % 97;
456
+ return remainder === checksum;
481
457
  };
482
458
  /**
483
459
  * Mod 97/10 calculation
@@ -487,7 +463,11 @@ var checkBelgianBBAN = function (bban) {
487
463
  var mod9710 = function (validationString) {
488
464
  while (validationString.length > 2) {
489
465
  var part = validationString.slice(0, 6);
490
- validationString = (parseInt(part, 10) % 97).toString() + validationString.slice(part.length);
466
+ var value = parseInt(part, 10) % 97;
467
+ if (isNaN(value)) {
468
+ return NaN;
469
+ }
470
+ validationString = value.toString() + validationString.slice(part.length);
491
471
  }
492
472
  return parseInt(validationString, 10) % 97;
493
473
  };
@@ -545,6 +525,213 @@ var checkSpainBBAN = function (bban) {
545
525
  remainder = sum % 11;
546
526
  return controlAccount === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
547
527
  };
528
+ /**
529
+ * Mod 11/10 check
530
+ *
531
+ * @ignore
532
+ */
533
+ var checkMod1110 = function (toCheck, control) {
534
+ var nr = 10;
535
+ for (var index = 0; index < toCheck.length; index++) {
536
+ nr += parseInt(toCheck.charAt(index), 10);
537
+ if (nr % 10 !== 0) {
538
+ nr = nr % 10;
539
+ }
540
+ nr = nr * 2;
541
+ nr = nr % 11;
542
+ }
543
+ return control === (11 - nr === 10 ? 0 : 11 - nr);
544
+ };
545
+ /**
546
+ * Croatian (HR) BBAN check
547
+ *
548
+ * @ignore
549
+ */
550
+ var checkCroatianBBAN = function (bban) {
551
+ var controlBankBranch = parseInt(bban.charAt(6), 10);
552
+ var controlAccount = parseInt(bban.charAt(16), 10);
553
+ var bankBranch = bban.substring(0, 6);
554
+ var account = bban.substring(7, 16);
555
+ return checkMod1110(bankBranch, controlBankBranch) && checkMod1110(account, controlAccount);
556
+ };
557
+ /**
558
+ * Czech (CZ) BBAN check
559
+ *
560
+ * @ignore
561
+ */
562
+ var checkCzechBBAN = function (bban) {
563
+ var weightsPrefix = [10, 5, 8, 4, 2, 1];
564
+ var weightsSuffix = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
565
+ var controlPrefix = parseInt(bban.charAt(9), 10);
566
+ var controlSuffix = parseInt(bban.charAt(19), 10);
567
+ var prefix = bban.substring(4, 9);
568
+ var suffix = bban.substring(10, 19);
569
+ var sum = 0;
570
+ for (var index = 0; index < prefix.length; index++) {
571
+ sum += parseInt(prefix.charAt(index), 10) * weightsPrefix[index];
572
+ }
573
+ var remainder = sum % 11;
574
+ if (controlPrefix !== (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder)) {
575
+ return false;
576
+ }
577
+ sum = 0;
578
+ for (var index = 0; index < suffix.length; index++) {
579
+ sum += parseInt(suffix.charAt(index), 10) * weightsSuffix[index];
580
+ }
581
+ remainder = sum % 11;
582
+ return controlSuffix === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
583
+ };
584
+ /**
585
+ * Estonian (EE) BBAN check
586
+ *
587
+ * @ignore
588
+ */
589
+ var checkEstonianBBAN = function (bban) {
590
+ var weights = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7];
591
+ var controlDigit = parseInt(bban.charAt(15), 10);
592
+ var toCheck = bban.substring(2, 15);
593
+ var sum = 0;
594
+ for (var index = 0; index < toCheck.length; index++) {
595
+ sum += parseInt(toCheck.charAt(index), 10) * weights[index];
596
+ }
597
+ var remainder = sum % 10;
598
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
599
+ };
600
+ /**
601
+ * Finland (FI) BBAN check
602
+ *
603
+ * @ignore
604
+ */
605
+ var checkFinlandBBAN = function (bban) {
606
+ var weightsMethod1 = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2];
607
+ var weightsMethod2 = [0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 1, 3, 7];
608
+ var controlDigit = parseInt(bban.charAt(13), 10);
609
+ var toCheck = bban.substring(0, 13);
610
+ var sum = 0;
611
+ if (toCheck.startsWith('88')) {
612
+ for (var index = 0; index < toCheck.length; index++) {
613
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod2[index];
614
+ }
615
+ var remainder = sum % 10;
616
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
617
+ }
618
+ else {
619
+ for (var index = 0; index < toCheck.length; index++) {
620
+ if (weightsMethod1[index] === 1) {
621
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
622
+ }
623
+ else {
624
+ var value = parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
625
+ sum += Math.floor(value / 10) + (value % 10);
626
+ }
627
+ }
628
+ var extraSum = sum + controlDigit;
629
+ var multiDigit = Math.floor(extraSum / 10);
630
+ var result = multiDigit * 10;
631
+ var remainder = result - sum;
632
+ return remainder === controlDigit;
633
+ }
634
+ };
635
+ /**
636
+ * Check French (FR) BBAN
637
+ * Also for Monaco (MC)
638
+ *
639
+ * @ignore
640
+ */
641
+ var checkFrenchBBAN = function (bban) {
642
+ var stripped = bban.replace(/[\s.]+/g, '');
643
+ var normalized = Array.from(stripped);
644
+ for (var index = 0; index < stripped.length; index++) {
645
+ var c = normalized[index].charCodeAt(0);
646
+ if (c >= 65) {
647
+ switch (c) {
648
+ case 65:
649
+ case 74:
650
+ normalized[index] = '1';
651
+ break;
652
+ case 66:
653
+ case 75:
654
+ case 83:
655
+ normalized[index] = '2';
656
+ break;
657
+ case 67:
658
+ case 76:
659
+ case 84:
660
+ normalized[index] = '3';
661
+ break;
662
+ case 68:
663
+ case 77:
664
+ case 85:
665
+ normalized[index] = '4';
666
+ break;
667
+ case 69:
668
+ case 78:
669
+ case 86:
670
+ normalized[index] = '5';
671
+ break;
672
+ case 70:
673
+ case 79:
674
+ case 87:
675
+ normalized[index] = '6';
676
+ break;
677
+ case 71:
678
+ case 80:
679
+ case 88:
680
+ normalized[index] = '7';
681
+ break;
682
+ case 72:
683
+ case 81:
684
+ case 89:
685
+ normalized[index] = '8';
686
+ break;
687
+ case 73:
688
+ case 82:
689
+ case 90:
690
+ normalized[index] = '9';
691
+ break;
692
+ }
693
+ }
694
+ }
695
+ var remainder = mod9710(normalized.join(''));
696
+ return remainder === 0;
697
+ };
698
+ /**
699
+ * Hungarian (HU) BBAN check
700
+ *
701
+ * @ignore
702
+ */
703
+ var checkHungarianBBAN = function (bban) {
704
+ var weights = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3];
705
+ var controlDigitBankBranch = parseInt(bban.charAt(7), 10);
706
+ var toCheckBankBranch = bban.substring(0, 7);
707
+ var sum = 0;
708
+ for (var index = 0; index < toCheckBankBranch.length; index++) {
709
+ sum += parseInt(toCheckBankBranch.charAt(index), 10) * weights[index];
710
+ }
711
+ var remainder = sum % 10;
712
+ if (controlDigitBankBranch !== (remainder === 0 ? 0 : 10 - remainder)) {
713
+ return false;
714
+ }
715
+ sum = 0;
716
+ if (bban.endsWith('00000000')) {
717
+ var toCheckAccount = bban.substring(8, 15);
718
+ var controlDigitAccount = parseInt(bban.charAt(15), 10);
719
+ for (var index = 0; index < toCheckAccount.length; index++) {
720
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
721
+ }
722
+ var remainder_1 = sum % 10;
723
+ return controlDigitAccount === (remainder_1 === 0 ? 0 : 10 - remainder_1);
724
+ }
725
+ else {
726
+ var toCheckAccount = bban.substring(8, 23);
727
+ var controlDigitAccount = parseInt(bban.charAt(23), 10);
728
+ for (var index = 0; index < toCheckAccount.length; index++) {
729
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
730
+ }
731
+ var remainder_2 = sum % 10;
732
+ return controlDigitAccount === (remainder_2 === 0 ? 0 : 10 - remainder_2);
733
+ }
734
+ };
548
735
  /**
549
736
  * Country specifications
550
737
  */
@@ -582,6 +769,7 @@ exports.countrySpecs = {
582
769
  AX: {
583
770
  chars: 18,
584
771
  bban_regexp: '^[0-9]{14}$',
772
+ bban_validation_func: checkFinlandBBAN,
585
773
  IBANRegistry: true,
586
774
  },
587
775
  AZ: {
@@ -689,7 +877,13 @@ exports.countrySpecs = {
689
877
  IBANRegistry: true,
690
878
  SEPA: true,
691
879
  },
692
- CZ: { chars: 24, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
880
+ CZ: {
881
+ chars: 24,
882
+ bban_regexp: '^[0-9]{20}$',
883
+ bban_validation_func: checkCzechBBAN,
884
+ IBANRegistry: true,
885
+ SEPA: true,
886
+ },
693
887
  DE: { chars: 22, bban_regexp: '^[0-9]{18}$', IBANRegistry: true, SEPA: true },
694
888
  DJ: {
695
889
  chars: 27,
@@ -707,13 +901,31 @@ exports.countrySpecs = {
707
901
  bban_regexp: '^[0-9]{22}$',
708
902
  },
709
903
  EC: {},
710
- EE: { chars: 20, bban_regexp: '^[0-9]{16}$', IBANRegistry: true, SEPA: true },
904
+ EE: {
905
+ chars: 20,
906
+ bban_regexp: '^[0-9]{16}$',
907
+ bban_validation_func: checkEstonianBBAN,
908
+ IBANRegistry: true,
909
+ SEPA: true,
910
+ },
711
911
  EG: { chars: 29, bban_regexp: '^[0-9]{25}', IBANRegistry: true },
712
912
  EH: {},
713
913
  ER: {},
714
- ES: { chars: 24, bban_validation_func: checkSpainBBAN, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
914
+ ES: {
915
+ chars: 24,
916
+ bban_validation_func: checkSpainBBAN,
917
+ bban_regexp: '^[0-9]{20}$',
918
+ IBANRegistry: true,
919
+ SEPA: true,
920
+ },
715
921
  ET: {},
716
- FI: { chars: 18, bban_regexp: '^[0-9]{14}$', IBANRegistry: true, SEPA: true },
922
+ FI: {
923
+ chars: 18,
924
+ bban_regexp: '^[0-9]{14}$',
925
+ bban_validation_func: checkFinlandBBAN,
926
+ IBANRegistry: true,
927
+ SEPA: true,
928
+ },
717
929
  FJ: {},
718
930
  FK: {},
719
931
  FM: {},
@@ -721,6 +933,7 @@ exports.countrySpecs = {
721
933
  FR: {
722
934
  chars: 27,
723
935
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
936
+ bban_validation_func: checkFrenchBBAN,
724
937
  IBANRegistry: true,
725
938
  SEPA: true,
726
939
  },
@@ -789,9 +1002,21 @@ exports.countrySpecs = {
789
1002
  chars: 28,
790
1003
  bban_regexp: '^[A-Z]{4}[0-9]{20}$',
791
1004
  },
792
- HR: { chars: 21, bban_regexp: '^[0-9]{17}$', IBANRegistry: true, SEPA: true },
1005
+ HR: {
1006
+ chars: 21,
1007
+ bban_regexp: '^[0-9]{17}$',
1008
+ bban_validation_func: checkCroatianBBAN,
1009
+ IBANRegistry: true,
1010
+ SEPA: true,
1011
+ },
793
1012
  HT: {},
794
- HU: { chars: 28, bban_regexp: '^[0-9]{24}$', IBANRegistry: true, SEPA: true },
1013
+ HU: {
1014
+ chars: 28,
1015
+ bban_regexp: '^[0-9]{24}$',
1016
+ bban_validation_func: checkHungarianBBAN,
1017
+ IBANRegistry: true,
1018
+ SEPA: true,
1019
+ },
795
1020
  ID: {},
796
1021
  IE: {
797
1022
  chars: 22,
@@ -898,6 +1123,7 @@ exports.countrySpecs = {
898
1123
  MC: {
899
1124
  chars: 27,
900
1125
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
1126
+ bban_validation_func: checkFrenchBBAN,
901
1127
  IBANRegistry: true,
902
1128
  SEPA: true,
903
1129
  },
@@ -985,7 +1211,6 @@ exports.countrySpecs = {
985
1211
  NL: {
986
1212
  chars: 18,
987
1213
  bban_regexp: '^[A-Z]{4}[0-9]{10}$',
988
- bban_validation_func: checkDutchBBAN,
989
1214
  IBANRegistry: true,
990
1215
  SEPA: true,
991
1216
  },
@@ -8,7 +8,7 @@
8
8
  * @package Documentation
9
9
  * @author Saša Jovanić
10
10
  * @module ibantools
11
- * @version 4.1.0
11
+ * @version 4.1.4
12
12
  * @license MPL-2.0
13
13
  * @preferred
14
14
  */
@@ -68,6 +68,7 @@ export function validateIBAN(iban) {
68
68
  if (!spec || !(spec.bban_regexp || spec.chars)) {
69
69
  result.valid = false;
70
70
  result.errorCodes.push(ValidationErrorsIBAN.NoIBANCountry);
71
+ return result;
71
72
  }
72
73
  if (spec && spec.chars && spec.chars !== iban.length) {
73
74
  result.valid = false;
@@ -419,36 +420,14 @@ export function extractBIC(inputBic) {
419
420
  var checkNorwayBBAN = function (bban) {
420
421
  var weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
421
422
  var bbanWithoutSpacesAndPeriods = bban.replace(/[\s.]+/g, '');
422
- if (bbanWithoutSpacesAndPeriods.length !== 11) {
423
- return false;
424
- }
425
- else {
426
- var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);
427
- var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);
428
- var sum = 0;
429
- for (var index = 0; index < 10; index++) {
430
- sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];
431
- }
432
- var remainder = sum % 11;
433
- return controlDigit === (remainder === 0 ? 0 : 11 - remainder);
434
- }
435
- };
436
- /**
437
- * Used for Netherlands BBAN check
438
- *
439
- * @ignore
440
- */
441
- var checkDutchBBAN = function (bban) {
442
- var bbanWithoutSpacesAndPeriods = bban.replace(/[\s.]+/g, '');
443
- var accountNumber = bbanWithoutSpacesAndPeriods.substring(4, 14);
444
- if (accountNumber.startsWith('000')) {
445
- return true; // Postbank account, no `elfproef` possible
446
- }
423
+ var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);
424
+ var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);
447
425
  var sum = 0;
448
426
  for (var index = 0; index < 10; index++) {
449
- sum += parseInt(accountNumber.charAt(index), 10) * (10 - index);
427
+ sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];
450
428
  }
451
- return sum % 11 === 0;
429
+ var remainder = sum % 11;
430
+ return controlDigit === (remainder === 0 ? 0 : 11 - remainder);
452
431
  };
453
432
  /**
454
433
  * Used for Belgian BBAN check
@@ -459,11 +438,8 @@ var checkBelgianBBAN = function (bban) {
459
438
  var stripped = bban.replace(/[\s.]+/g, '');
460
439
  var checkingPart = parseInt(stripped.substring(0, stripped.length - 2), 10);
461
440
  var checksum = parseInt(stripped.substring(stripped.length - 2, stripped.length), 10);
462
- var reminder = checkingPart % 97;
463
- if (reminder === 0) {
464
- reminder = 97;
465
- }
466
- return reminder === checksum;
441
+ var remainder = checkingPart % 97 === 0 ? 97 : checkingPart % 97;
442
+ return remainder === checksum;
467
443
  };
468
444
  /**
469
445
  * Mod 97/10 calculation
@@ -473,7 +449,11 @@ var checkBelgianBBAN = function (bban) {
473
449
  var mod9710 = function (validationString) {
474
450
  while (validationString.length > 2) {
475
451
  var part = validationString.slice(0, 6);
476
- validationString = (parseInt(part, 10) % 97).toString() + validationString.slice(part.length);
452
+ var value = parseInt(part, 10) % 97;
453
+ if (isNaN(value)) {
454
+ return NaN;
455
+ }
456
+ validationString = value.toString() + validationString.slice(part.length);
477
457
  }
478
458
  return parseInt(validationString, 10) % 97;
479
459
  };
@@ -531,6 +511,213 @@ var checkSpainBBAN = function (bban) {
531
511
  remainder = sum % 11;
532
512
  return controlAccount === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
533
513
  };
514
+ /**
515
+ * Mod 11/10 check
516
+ *
517
+ * @ignore
518
+ */
519
+ var checkMod1110 = function (toCheck, control) {
520
+ var nr = 10;
521
+ for (var index = 0; index < toCheck.length; index++) {
522
+ nr += parseInt(toCheck.charAt(index), 10);
523
+ if (nr % 10 !== 0) {
524
+ nr = nr % 10;
525
+ }
526
+ nr = nr * 2;
527
+ nr = nr % 11;
528
+ }
529
+ return control === (11 - nr === 10 ? 0 : 11 - nr);
530
+ };
531
+ /**
532
+ * Croatian (HR) BBAN check
533
+ *
534
+ * @ignore
535
+ */
536
+ var checkCroatianBBAN = function (bban) {
537
+ var controlBankBranch = parseInt(bban.charAt(6), 10);
538
+ var controlAccount = parseInt(bban.charAt(16), 10);
539
+ var bankBranch = bban.substring(0, 6);
540
+ var account = bban.substring(7, 16);
541
+ return checkMod1110(bankBranch, controlBankBranch) && checkMod1110(account, controlAccount);
542
+ };
543
+ /**
544
+ * Czech (CZ) BBAN check
545
+ *
546
+ * @ignore
547
+ */
548
+ var checkCzechBBAN = function (bban) {
549
+ var weightsPrefix = [10, 5, 8, 4, 2, 1];
550
+ var weightsSuffix = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
551
+ var controlPrefix = parseInt(bban.charAt(9), 10);
552
+ var controlSuffix = parseInt(bban.charAt(19), 10);
553
+ var prefix = bban.substring(4, 9);
554
+ var suffix = bban.substring(10, 19);
555
+ var sum = 0;
556
+ for (var index = 0; index < prefix.length; index++) {
557
+ sum += parseInt(prefix.charAt(index), 10) * weightsPrefix[index];
558
+ }
559
+ var remainder = sum % 11;
560
+ if (controlPrefix !== (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder)) {
561
+ return false;
562
+ }
563
+ sum = 0;
564
+ for (var index = 0; index < suffix.length; index++) {
565
+ sum += parseInt(suffix.charAt(index), 10) * weightsSuffix[index];
566
+ }
567
+ remainder = sum % 11;
568
+ return controlSuffix === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
569
+ };
570
+ /**
571
+ * Estonian (EE) BBAN check
572
+ *
573
+ * @ignore
574
+ */
575
+ var checkEstonianBBAN = function (bban) {
576
+ var weights = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7];
577
+ var controlDigit = parseInt(bban.charAt(15), 10);
578
+ var toCheck = bban.substring(2, 15);
579
+ var sum = 0;
580
+ for (var index = 0; index < toCheck.length; index++) {
581
+ sum += parseInt(toCheck.charAt(index), 10) * weights[index];
582
+ }
583
+ var remainder = sum % 10;
584
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
585
+ };
586
+ /**
587
+ * Finland (FI) BBAN check
588
+ *
589
+ * @ignore
590
+ */
591
+ var checkFinlandBBAN = function (bban) {
592
+ var weightsMethod1 = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2];
593
+ var weightsMethod2 = [0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 1, 3, 7];
594
+ var controlDigit = parseInt(bban.charAt(13), 10);
595
+ var toCheck = bban.substring(0, 13);
596
+ var sum = 0;
597
+ if (toCheck.startsWith('88')) {
598
+ for (var index = 0; index < toCheck.length; index++) {
599
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod2[index];
600
+ }
601
+ var remainder = sum % 10;
602
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
603
+ }
604
+ else {
605
+ for (var index = 0; index < toCheck.length; index++) {
606
+ if (weightsMethod1[index] === 1) {
607
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
608
+ }
609
+ else {
610
+ var value = parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
611
+ sum += Math.floor(value / 10) + (value % 10);
612
+ }
613
+ }
614
+ var extraSum = sum + controlDigit;
615
+ var multiDigit = Math.floor(extraSum / 10);
616
+ var result = multiDigit * 10;
617
+ var remainder = result - sum;
618
+ return remainder === controlDigit;
619
+ }
620
+ };
621
+ /**
622
+ * Check French (FR) BBAN
623
+ * Also for Monaco (MC)
624
+ *
625
+ * @ignore
626
+ */
627
+ var checkFrenchBBAN = function (bban) {
628
+ var stripped = bban.replace(/[\s.]+/g, '');
629
+ var normalized = Array.from(stripped);
630
+ for (var index = 0; index < stripped.length; index++) {
631
+ var c = normalized[index].charCodeAt(0);
632
+ if (c >= 65) {
633
+ switch (c) {
634
+ case 65:
635
+ case 74:
636
+ normalized[index] = '1';
637
+ break;
638
+ case 66:
639
+ case 75:
640
+ case 83:
641
+ normalized[index] = '2';
642
+ break;
643
+ case 67:
644
+ case 76:
645
+ case 84:
646
+ normalized[index] = '3';
647
+ break;
648
+ case 68:
649
+ case 77:
650
+ case 85:
651
+ normalized[index] = '4';
652
+ break;
653
+ case 69:
654
+ case 78:
655
+ case 86:
656
+ normalized[index] = '5';
657
+ break;
658
+ case 70:
659
+ case 79:
660
+ case 87:
661
+ normalized[index] = '6';
662
+ break;
663
+ case 71:
664
+ case 80:
665
+ case 88:
666
+ normalized[index] = '7';
667
+ break;
668
+ case 72:
669
+ case 81:
670
+ case 89:
671
+ normalized[index] = '8';
672
+ break;
673
+ case 73:
674
+ case 82:
675
+ case 90:
676
+ normalized[index] = '9';
677
+ break;
678
+ }
679
+ }
680
+ }
681
+ var remainder = mod9710(normalized.join(''));
682
+ return remainder === 0;
683
+ };
684
+ /**
685
+ * Hungarian (HU) BBAN check
686
+ *
687
+ * @ignore
688
+ */
689
+ var checkHungarianBBAN = function (bban) {
690
+ var weights = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3];
691
+ var controlDigitBankBranch = parseInt(bban.charAt(7), 10);
692
+ var toCheckBankBranch = bban.substring(0, 7);
693
+ var sum = 0;
694
+ for (var index = 0; index < toCheckBankBranch.length; index++) {
695
+ sum += parseInt(toCheckBankBranch.charAt(index), 10) * weights[index];
696
+ }
697
+ var remainder = sum % 10;
698
+ if (controlDigitBankBranch !== (remainder === 0 ? 0 : 10 - remainder)) {
699
+ return false;
700
+ }
701
+ sum = 0;
702
+ if (bban.endsWith('00000000')) {
703
+ var toCheckAccount = bban.substring(8, 15);
704
+ var controlDigitAccount = parseInt(bban.charAt(15), 10);
705
+ for (var index = 0; index < toCheckAccount.length; index++) {
706
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
707
+ }
708
+ var remainder_1 = sum % 10;
709
+ return controlDigitAccount === (remainder_1 === 0 ? 0 : 10 - remainder_1);
710
+ }
711
+ else {
712
+ var toCheckAccount = bban.substring(8, 23);
713
+ var controlDigitAccount = parseInt(bban.charAt(23), 10);
714
+ for (var index = 0; index < toCheckAccount.length; index++) {
715
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
716
+ }
717
+ var remainder_2 = sum % 10;
718
+ return controlDigitAccount === (remainder_2 === 0 ? 0 : 10 - remainder_2);
719
+ }
720
+ };
534
721
  /**
535
722
  * Country specifications
536
723
  */
@@ -568,6 +755,7 @@ export var countrySpecs = {
568
755
  AX: {
569
756
  chars: 18,
570
757
  bban_regexp: '^[0-9]{14}$',
758
+ bban_validation_func: checkFinlandBBAN,
571
759
  IBANRegistry: true,
572
760
  },
573
761
  AZ: {
@@ -675,7 +863,13 @@ export var countrySpecs = {
675
863
  IBANRegistry: true,
676
864
  SEPA: true,
677
865
  },
678
- CZ: { chars: 24, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
866
+ CZ: {
867
+ chars: 24,
868
+ bban_regexp: '^[0-9]{20}$',
869
+ bban_validation_func: checkCzechBBAN,
870
+ IBANRegistry: true,
871
+ SEPA: true,
872
+ },
679
873
  DE: { chars: 22, bban_regexp: '^[0-9]{18}$', IBANRegistry: true, SEPA: true },
680
874
  DJ: {
681
875
  chars: 27,
@@ -693,13 +887,31 @@ export var countrySpecs = {
693
887
  bban_regexp: '^[0-9]{22}$',
694
888
  },
695
889
  EC: {},
696
- EE: { chars: 20, bban_regexp: '^[0-9]{16}$', IBANRegistry: true, SEPA: true },
890
+ EE: {
891
+ chars: 20,
892
+ bban_regexp: '^[0-9]{16}$',
893
+ bban_validation_func: checkEstonianBBAN,
894
+ IBANRegistry: true,
895
+ SEPA: true,
896
+ },
697
897
  EG: { chars: 29, bban_regexp: '^[0-9]{25}', IBANRegistry: true },
698
898
  EH: {},
699
899
  ER: {},
700
- ES: { chars: 24, bban_validation_func: checkSpainBBAN, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
900
+ ES: {
901
+ chars: 24,
902
+ bban_validation_func: checkSpainBBAN,
903
+ bban_regexp: '^[0-9]{20}$',
904
+ IBANRegistry: true,
905
+ SEPA: true,
906
+ },
701
907
  ET: {},
702
- FI: { chars: 18, bban_regexp: '^[0-9]{14}$', IBANRegistry: true, SEPA: true },
908
+ FI: {
909
+ chars: 18,
910
+ bban_regexp: '^[0-9]{14}$',
911
+ bban_validation_func: checkFinlandBBAN,
912
+ IBANRegistry: true,
913
+ SEPA: true,
914
+ },
703
915
  FJ: {},
704
916
  FK: {},
705
917
  FM: {},
@@ -707,6 +919,7 @@ export var countrySpecs = {
707
919
  FR: {
708
920
  chars: 27,
709
921
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
922
+ bban_validation_func: checkFrenchBBAN,
710
923
  IBANRegistry: true,
711
924
  SEPA: true,
712
925
  },
@@ -775,9 +988,21 @@ export var countrySpecs = {
775
988
  chars: 28,
776
989
  bban_regexp: '^[A-Z]{4}[0-9]{20}$',
777
990
  },
778
- HR: { chars: 21, bban_regexp: '^[0-9]{17}$', IBANRegistry: true, SEPA: true },
991
+ HR: {
992
+ chars: 21,
993
+ bban_regexp: '^[0-9]{17}$',
994
+ bban_validation_func: checkCroatianBBAN,
995
+ IBANRegistry: true,
996
+ SEPA: true,
997
+ },
779
998
  HT: {},
780
- HU: { chars: 28, bban_regexp: '^[0-9]{24}$', IBANRegistry: true, SEPA: true },
999
+ HU: {
1000
+ chars: 28,
1001
+ bban_regexp: '^[0-9]{24}$',
1002
+ bban_validation_func: checkHungarianBBAN,
1003
+ IBANRegistry: true,
1004
+ SEPA: true,
1005
+ },
781
1006
  ID: {},
782
1007
  IE: {
783
1008
  chars: 22,
@@ -884,6 +1109,7 @@ export var countrySpecs = {
884
1109
  MC: {
885
1110
  chars: 27,
886
1111
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
1112
+ bban_validation_func: checkFrenchBBAN,
887
1113
  IBANRegistry: true,
888
1114
  SEPA: true,
889
1115
  },
@@ -971,7 +1197,6 @@ export var countrySpecs = {
971
1197
  NL: {
972
1198
  chars: 18,
973
1199
  bban_regexp: '^[A-Z]{4}[0-9]{10}$',
974
- bban_validation_func: checkDutchBBAN,
975
1200
  IBANRegistry: true,
976
1201
  SEPA: true,
977
1202
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ibantools",
3
- "version": "4.1.0",
3
+ "version": "4.1.4",
4
4
  "description": "Validation, extraction and creation of IBAN, BBAN, BIC/SWIFT numbers plus some other helpful stuff like ISO 3136-1 alpha 2 country list",
5
5
  "keywords": [
6
6
  "IBAN",
@@ -64,7 +64,7 @@
64
64
  "gulp-rename": "^2.0",
65
65
  "gulp-shell": "^0.8.0",
66
66
  "gulp-typescript": "^5.0",
67
- "jasmine-core": "^3.8.0",
67
+ "jasmine-core": "^4.0.0",
68
68
  "karma": "^6.3.4",
69
69
  "karma-chrome-launcher": "^3.1",
70
70
  "karma-jasmine": "^4.0",