ibantools 4.1.0 → 4.1.1

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,21 @@
1
+ 2021-12-05 Saša Jovanić <sasa@simplify.ba>
2
+ * Added Hungarian (HU) BBAN validation
3
+
4
+ 2021-12-01 Saša Jovanić <sasa@simplify.ba>
5
+ * Improve test coverage
6
+
7
+ 2021-11-30 Saša Jovanić <sasa@simplify.ba>
8
+ * Added Estonian (EE) BBAN validation
9
+ * Added Finland (FI) BBAN validation
10
+ * Aland Islands (AX) uses BBAN valkidation from Finland
11
+ * Added French (FR) and Monaco (MC) BBAN validation
12
+
13
+ 2021-11-28 Saša Jovanić <sasa@simplify.ba>
14
+ * Added Czech (CZ) BBAN validation
15
+
16
+ 2021-11-27 Saša Jovanić <sasa@simplify.ba>
17
+ * Added Croatian (HR) BBAN validation
18
+
1
19
  2021-11-25 Saša Jovanić <sasa@simplify.ba>
2
20
  * Version 4.1.0
3
21
  * 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.1
12
12
  * @license MPL-2.0
13
13
  * @preferred
14
14
  */
@@ -433,19 +433,14 @@ exports.extractBIC = extractBIC;
433
433
  var checkNorwayBBAN = function (bban) {
434
434
  var weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
435
435
  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);
436
+ var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);
437
+ var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);
438
+ var sum = 0;
439
+ for (var index = 0; index < 10; index++) {
440
+ sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];
448
441
  }
442
+ var remainder = sum % 11;
443
+ return controlDigit === (remainder === 0 ? 0 : 11 - remainder);
449
444
  };
450
445
  /**
451
446
  * Used for Netherlands BBAN check
@@ -473,11 +468,8 @@ var checkBelgianBBAN = function (bban) {
473
468
  var stripped = bban.replace(/[\s.]+/g, '');
474
469
  var checkingPart = parseInt(stripped.substring(0, stripped.length - 2), 10);
475
470
  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;
471
+ var remainder = checkingPart % 97 === 0 ? 97 : checkingPart % 97;
472
+ return remainder === checksum;
481
473
  };
482
474
  /**
483
475
  * Mod 97/10 calculation
@@ -545,6 +537,213 @@ var checkSpainBBAN = function (bban) {
545
537
  remainder = sum % 11;
546
538
  return controlAccount === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
547
539
  };
540
+ /**
541
+ * Mod 11/10 check
542
+ *
543
+ * @ignore
544
+ */
545
+ var checkMod1110 = function (toCheck, control) {
546
+ var nr = 10;
547
+ for (var index = 0; index < toCheck.length; index++) {
548
+ nr += parseInt(toCheck.charAt(index), 10);
549
+ if (nr % 10 !== 0) {
550
+ nr = nr % 10;
551
+ }
552
+ nr = nr * 2;
553
+ nr = nr % 11;
554
+ }
555
+ return control === (11 - nr === 10 ? 0 : 11 - nr);
556
+ };
557
+ /**
558
+ * Croatian (HR) BBAN check
559
+ *
560
+ * @ignore
561
+ */
562
+ var checkCroatianBBAN = function (bban) {
563
+ var controlBankBranch = parseInt(bban.charAt(6), 10);
564
+ var controlAccount = parseInt(bban.charAt(16), 10);
565
+ var bankBranch = bban.substring(0, 6);
566
+ var account = bban.substring(7, 16);
567
+ return checkMod1110(bankBranch, controlBankBranch) && checkMod1110(account, controlAccount);
568
+ };
569
+ /**
570
+ * Czech (CZ) BBAN check
571
+ *
572
+ * @ignore
573
+ */
574
+ var checkCzechBBAN = function (bban) {
575
+ var weightsPrefix = [10, 5, 8, 4, 2, 1];
576
+ var weightsSuffix = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
577
+ var controlPrefix = parseInt(bban.charAt(9), 10);
578
+ var controlSuffix = parseInt(bban.charAt(19), 10);
579
+ var prefix = bban.substring(4, 9);
580
+ var suffix = bban.substring(10, 19);
581
+ var sum = 0;
582
+ for (var index = 0; index < prefix.length; index++) {
583
+ sum += parseInt(prefix.charAt(index), 10) * weightsPrefix[index];
584
+ }
585
+ var remainder = sum % 11;
586
+ if (controlPrefix !== (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder)) {
587
+ return false;
588
+ }
589
+ sum = 0;
590
+ for (var index = 0; index < suffix.length; index++) {
591
+ sum += parseInt(suffix.charAt(index), 10) * weightsSuffix[index];
592
+ }
593
+ remainder = sum % 11;
594
+ return controlSuffix === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
595
+ };
596
+ /**
597
+ * Estonian (EE) BBAN check
598
+ *
599
+ * @ignore
600
+ */
601
+ var checkEstonianBBAN = function (bban) {
602
+ var weights = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7];
603
+ var controlDigit = parseInt(bban.charAt(15), 10);
604
+ var toCheck = bban.substring(2, 15);
605
+ var sum = 0;
606
+ for (var index = 0; index < toCheck.length; index++) {
607
+ sum += parseInt(toCheck.charAt(index), 10) * weights[index];
608
+ }
609
+ var remainder = sum % 10;
610
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
611
+ };
612
+ /**
613
+ * Finland (FI) BBAN check
614
+ *
615
+ * @ignore
616
+ */
617
+ var checkFinlandBBAN = function (bban) {
618
+ var weightsMethod1 = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2];
619
+ var weightsMethod2 = [0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 1, 3, 7];
620
+ var controlDigit = parseInt(bban.charAt(13), 10);
621
+ var toCheck = bban.substring(0, 13);
622
+ var sum = 0;
623
+ if (toCheck.startsWith('88')) {
624
+ for (var index = 0; index < toCheck.length; index++) {
625
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod2[index];
626
+ }
627
+ var remainder = sum % 10;
628
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
629
+ }
630
+ else {
631
+ for (var index = 0; index < toCheck.length; index++) {
632
+ if (weightsMethod1[index] === 1) {
633
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
634
+ }
635
+ else {
636
+ var value = parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
637
+ sum += Math.floor(value / 10) + (value % 10);
638
+ }
639
+ }
640
+ var extraSum = sum + controlDigit;
641
+ var multiDigit = Math.floor(extraSum / 10);
642
+ var result = multiDigit * 10;
643
+ var remainder = result - sum;
644
+ return remainder === controlDigit;
645
+ }
646
+ };
647
+ /**
648
+ * Check French (FR) BBAN
649
+ * Also for Monaco (MC)
650
+ *
651
+ * @ignore
652
+ */
653
+ var checkFrenchBBAN = function (bban) {
654
+ var stripped = bban.replace(/[\s.]+/g, '');
655
+ var normalized = Array.from(stripped);
656
+ for (var index = 0; index < stripped.length; index++) {
657
+ var c = normalized[index].charCodeAt(0);
658
+ if (c >= 65) {
659
+ switch (c) {
660
+ case 65:
661
+ case 74:
662
+ normalized[index] = '1';
663
+ break;
664
+ case 66:
665
+ case 75:
666
+ case 83:
667
+ normalized[index] = '2';
668
+ break;
669
+ case 67:
670
+ case 76:
671
+ case 84:
672
+ normalized[index] = '3';
673
+ break;
674
+ case 68:
675
+ case 77:
676
+ case 85:
677
+ normalized[index] = '4';
678
+ break;
679
+ case 69:
680
+ case 78:
681
+ case 86:
682
+ normalized[index] = '5';
683
+ break;
684
+ case 70:
685
+ case 79:
686
+ case 87:
687
+ normalized[index] = '6';
688
+ break;
689
+ case 71:
690
+ case 80:
691
+ case 88:
692
+ normalized[index] = '7';
693
+ break;
694
+ case 72:
695
+ case 81:
696
+ case 89:
697
+ normalized[index] = '8';
698
+ break;
699
+ case 73:
700
+ case 82:
701
+ case 90:
702
+ normalized[index] = '9';
703
+ break;
704
+ }
705
+ }
706
+ }
707
+ var remainder = mod9710(normalized.join(''));
708
+ return remainder === 0;
709
+ };
710
+ /**
711
+ * Hungarian (HU) BBAN check
712
+ *
713
+ * @ignore
714
+ */
715
+ var checkHungarianBBAN = function (bban) {
716
+ var weights = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3];
717
+ var controlDigitBankBranch = parseInt(bban.charAt(7), 10);
718
+ var toCheckBankBranch = bban.substring(0, 7);
719
+ var sum = 0;
720
+ for (var index = 0; index < toCheckBankBranch.length; index++) {
721
+ sum += parseInt(toCheckBankBranch.charAt(index), 10) * weights[index];
722
+ }
723
+ var remainder = sum % 10;
724
+ if (controlDigitBankBranch !== (remainder === 0 ? 0 : 10 - remainder)) {
725
+ return false;
726
+ }
727
+ sum = 0;
728
+ if (bban.endsWith('00000000')) {
729
+ var toCheckAccount = bban.substring(8, 15);
730
+ var controlDigitAccount = parseInt(bban.charAt(15), 10);
731
+ for (var index = 0; index < toCheckAccount.length; index++) {
732
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
733
+ }
734
+ var remainder_1 = sum % 10;
735
+ return controlDigitAccount === (remainder_1 === 0 ? 0 : 10 - remainder_1);
736
+ }
737
+ else {
738
+ var toCheckAccount = bban.substring(8, 23);
739
+ var controlDigitAccount = parseInt(bban.charAt(23), 10);
740
+ for (var index = 0; index < toCheckAccount.length; index++) {
741
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
742
+ }
743
+ var remainder_2 = sum % 10;
744
+ return controlDigitAccount === (remainder_2 === 0 ? 0 : 10 - remainder_2);
745
+ }
746
+ };
548
747
  /**
549
748
  * Country specifications
550
749
  */
@@ -582,6 +781,7 @@ exports.countrySpecs = {
582
781
  AX: {
583
782
  chars: 18,
584
783
  bban_regexp: '^[0-9]{14}$',
784
+ bban_validation_func: checkFinlandBBAN,
585
785
  IBANRegistry: true,
586
786
  },
587
787
  AZ: {
@@ -689,7 +889,13 @@ exports.countrySpecs = {
689
889
  IBANRegistry: true,
690
890
  SEPA: true,
691
891
  },
692
- CZ: { chars: 24, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
892
+ CZ: {
893
+ chars: 24,
894
+ bban_regexp: '^[0-9]{20}$',
895
+ bban_validation_func: checkCzechBBAN,
896
+ IBANRegistry: true,
897
+ SEPA: true,
898
+ },
693
899
  DE: { chars: 22, bban_regexp: '^[0-9]{18}$', IBANRegistry: true, SEPA: true },
694
900
  DJ: {
695
901
  chars: 27,
@@ -707,13 +913,31 @@ exports.countrySpecs = {
707
913
  bban_regexp: '^[0-9]{22}$',
708
914
  },
709
915
  EC: {},
710
- EE: { chars: 20, bban_regexp: '^[0-9]{16}$', IBANRegistry: true, SEPA: true },
916
+ EE: {
917
+ chars: 20,
918
+ bban_regexp: '^[0-9]{16}$',
919
+ bban_validation_func: checkEstonianBBAN,
920
+ IBANRegistry: true,
921
+ SEPA: true,
922
+ },
711
923
  EG: { chars: 29, bban_regexp: '^[0-9]{25}', IBANRegistry: true },
712
924
  EH: {},
713
925
  ER: {},
714
- ES: { chars: 24, bban_validation_func: checkSpainBBAN, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
926
+ ES: {
927
+ chars: 24,
928
+ bban_validation_func: checkSpainBBAN,
929
+ bban_regexp: '^[0-9]{20}$',
930
+ IBANRegistry: true,
931
+ SEPA: true,
932
+ },
715
933
  ET: {},
716
- FI: { chars: 18, bban_regexp: '^[0-9]{14}$', IBANRegistry: true, SEPA: true },
934
+ FI: {
935
+ chars: 18,
936
+ bban_regexp: '^[0-9]{14}$',
937
+ bban_validation_func: checkFinlandBBAN,
938
+ IBANRegistry: true,
939
+ SEPA: true,
940
+ },
717
941
  FJ: {},
718
942
  FK: {},
719
943
  FM: {},
@@ -721,6 +945,7 @@ exports.countrySpecs = {
721
945
  FR: {
722
946
  chars: 27,
723
947
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
948
+ bban_validation_func: checkFrenchBBAN,
724
949
  IBANRegistry: true,
725
950
  SEPA: true,
726
951
  },
@@ -789,9 +1014,21 @@ exports.countrySpecs = {
789
1014
  chars: 28,
790
1015
  bban_regexp: '^[A-Z]{4}[0-9]{20}$',
791
1016
  },
792
- HR: { chars: 21, bban_regexp: '^[0-9]{17}$', IBANRegistry: true, SEPA: true },
1017
+ HR: {
1018
+ chars: 21,
1019
+ bban_regexp: '^[0-9]{17}$',
1020
+ bban_validation_func: checkCroatianBBAN,
1021
+ IBANRegistry: true,
1022
+ SEPA: true,
1023
+ },
793
1024
  HT: {},
794
- HU: { chars: 28, bban_regexp: '^[0-9]{24}$', IBANRegistry: true, SEPA: true },
1025
+ HU: {
1026
+ chars: 28,
1027
+ bban_regexp: '^[0-9]{24}$',
1028
+ bban_validation_func: checkHungarianBBAN,
1029
+ IBANRegistry: true,
1030
+ SEPA: true,
1031
+ },
795
1032
  ID: {},
796
1033
  IE: {
797
1034
  chars: 22,
@@ -898,6 +1135,7 @@ exports.countrySpecs = {
898
1135
  MC: {
899
1136
  chars: 27,
900
1137
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
1138
+ bban_validation_func: checkFrenchBBAN,
901
1139
  IBANRegistry: true,
902
1140
  SEPA: true,
903
1141
  },
@@ -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.1
12
12
  * @license MPL-2.0
13
13
  * @preferred
14
14
  */
@@ -419,19 +419,14 @@ export function extractBIC(inputBic) {
419
419
  var checkNorwayBBAN = function (bban) {
420
420
  var weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
421
421
  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);
422
+ var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);
423
+ var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);
424
+ var sum = 0;
425
+ for (var index = 0; index < 10; index++) {
426
+ sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];
434
427
  }
428
+ var remainder = sum % 11;
429
+ return controlDigit === (remainder === 0 ? 0 : 11 - remainder);
435
430
  };
436
431
  /**
437
432
  * Used for Netherlands BBAN check
@@ -459,11 +454,8 @@ var checkBelgianBBAN = function (bban) {
459
454
  var stripped = bban.replace(/[\s.]+/g, '');
460
455
  var checkingPart = parseInt(stripped.substring(0, stripped.length - 2), 10);
461
456
  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;
457
+ var remainder = checkingPart % 97 === 0 ? 97 : checkingPart % 97;
458
+ return remainder === checksum;
467
459
  };
468
460
  /**
469
461
  * Mod 97/10 calculation
@@ -531,6 +523,213 @@ var checkSpainBBAN = function (bban) {
531
523
  remainder = sum % 11;
532
524
  return controlAccount === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
533
525
  };
526
+ /**
527
+ * Mod 11/10 check
528
+ *
529
+ * @ignore
530
+ */
531
+ var checkMod1110 = function (toCheck, control) {
532
+ var nr = 10;
533
+ for (var index = 0; index < toCheck.length; index++) {
534
+ nr += parseInt(toCheck.charAt(index), 10);
535
+ if (nr % 10 !== 0) {
536
+ nr = nr % 10;
537
+ }
538
+ nr = nr * 2;
539
+ nr = nr % 11;
540
+ }
541
+ return control === (11 - nr === 10 ? 0 : 11 - nr);
542
+ };
543
+ /**
544
+ * Croatian (HR) BBAN check
545
+ *
546
+ * @ignore
547
+ */
548
+ var checkCroatianBBAN = function (bban) {
549
+ var controlBankBranch = parseInt(bban.charAt(6), 10);
550
+ var controlAccount = parseInt(bban.charAt(16), 10);
551
+ var bankBranch = bban.substring(0, 6);
552
+ var account = bban.substring(7, 16);
553
+ return checkMod1110(bankBranch, controlBankBranch) && checkMod1110(account, controlAccount);
554
+ };
555
+ /**
556
+ * Czech (CZ) BBAN check
557
+ *
558
+ * @ignore
559
+ */
560
+ var checkCzechBBAN = function (bban) {
561
+ var weightsPrefix = [10, 5, 8, 4, 2, 1];
562
+ var weightsSuffix = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
563
+ var controlPrefix = parseInt(bban.charAt(9), 10);
564
+ var controlSuffix = parseInt(bban.charAt(19), 10);
565
+ var prefix = bban.substring(4, 9);
566
+ var suffix = bban.substring(10, 19);
567
+ var sum = 0;
568
+ for (var index = 0; index < prefix.length; index++) {
569
+ sum += parseInt(prefix.charAt(index), 10) * weightsPrefix[index];
570
+ }
571
+ var remainder = sum % 11;
572
+ if (controlPrefix !== (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder)) {
573
+ return false;
574
+ }
575
+ sum = 0;
576
+ for (var index = 0; index < suffix.length; index++) {
577
+ sum += parseInt(suffix.charAt(index), 10) * weightsSuffix[index];
578
+ }
579
+ remainder = sum % 11;
580
+ return controlSuffix === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);
581
+ };
582
+ /**
583
+ * Estonian (EE) BBAN check
584
+ *
585
+ * @ignore
586
+ */
587
+ var checkEstonianBBAN = function (bban) {
588
+ var weights = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7];
589
+ var controlDigit = parseInt(bban.charAt(15), 10);
590
+ var toCheck = bban.substring(2, 15);
591
+ var sum = 0;
592
+ for (var index = 0; index < toCheck.length; index++) {
593
+ sum += parseInt(toCheck.charAt(index), 10) * weights[index];
594
+ }
595
+ var remainder = sum % 10;
596
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
597
+ };
598
+ /**
599
+ * Finland (FI) BBAN check
600
+ *
601
+ * @ignore
602
+ */
603
+ var checkFinlandBBAN = function (bban) {
604
+ var weightsMethod1 = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2];
605
+ var weightsMethod2 = [0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 1, 3, 7];
606
+ var controlDigit = parseInt(bban.charAt(13), 10);
607
+ var toCheck = bban.substring(0, 13);
608
+ var sum = 0;
609
+ if (toCheck.startsWith('88')) {
610
+ for (var index = 0; index < toCheck.length; index++) {
611
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod2[index];
612
+ }
613
+ var remainder = sum % 10;
614
+ return controlDigit === (remainder === 0 ? 0 : 10 - remainder);
615
+ }
616
+ else {
617
+ for (var index = 0; index < toCheck.length; index++) {
618
+ if (weightsMethod1[index] === 1) {
619
+ sum += parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
620
+ }
621
+ else {
622
+ var value = parseInt(toCheck.charAt(index), 10) * weightsMethod1[index];
623
+ sum += Math.floor(value / 10) + (value % 10);
624
+ }
625
+ }
626
+ var extraSum = sum + controlDigit;
627
+ var multiDigit = Math.floor(extraSum / 10);
628
+ var result = multiDigit * 10;
629
+ var remainder = result - sum;
630
+ return remainder === controlDigit;
631
+ }
632
+ };
633
+ /**
634
+ * Check French (FR) BBAN
635
+ * Also for Monaco (MC)
636
+ *
637
+ * @ignore
638
+ */
639
+ var checkFrenchBBAN = function (bban) {
640
+ var stripped = bban.replace(/[\s.]+/g, '');
641
+ var normalized = Array.from(stripped);
642
+ for (var index = 0; index < stripped.length; index++) {
643
+ var c = normalized[index].charCodeAt(0);
644
+ if (c >= 65) {
645
+ switch (c) {
646
+ case 65:
647
+ case 74:
648
+ normalized[index] = '1';
649
+ break;
650
+ case 66:
651
+ case 75:
652
+ case 83:
653
+ normalized[index] = '2';
654
+ break;
655
+ case 67:
656
+ case 76:
657
+ case 84:
658
+ normalized[index] = '3';
659
+ break;
660
+ case 68:
661
+ case 77:
662
+ case 85:
663
+ normalized[index] = '4';
664
+ break;
665
+ case 69:
666
+ case 78:
667
+ case 86:
668
+ normalized[index] = '5';
669
+ break;
670
+ case 70:
671
+ case 79:
672
+ case 87:
673
+ normalized[index] = '6';
674
+ break;
675
+ case 71:
676
+ case 80:
677
+ case 88:
678
+ normalized[index] = '7';
679
+ break;
680
+ case 72:
681
+ case 81:
682
+ case 89:
683
+ normalized[index] = '8';
684
+ break;
685
+ case 73:
686
+ case 82:
687
+ case 90:
688
+ normalized[index] = '9';
689
+ break;
690
+ }
691
+ }
692
+ }
693
+ var remainder = mod9710(normalized.join(''));
694
+ return remainder === 0;
695
+ };
696
+ /**
697
+ * Hungarian (HU) BBAN check
698
+ *
699
+ * @ignore
700
+ */
701
+ var checkHungarianBBAN = function (bban) {
702
+ var weights = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3];
703
+ var controlDigitBankBranch = parseInt(bban.charAt(7), 10);
704
+ var toCheckBankBranch = bban.substring(0, 7);
705
+ var sum = 0;
706
+ for (var index = 0; index < toCheckBankBranch.length; index++) {
707
+ sum += parseInt(toCheckBankBranch.charAt(index), 10) * weights[index];
708
+ }
709
+ var remainder = sum % 10;
710
+ if (controlDigitBankBranch !== (remainder === 0 ? 0 : 10 - remainder)) {
711
+ return false;
712
+ }
713
+ sum = 0;
714
+ if (bban.endsWith('00000000')) {
715
+ var toCheckAccount = bban.substring(8, 15);
716
+ var controlDigitAccount = parseInt(bban.charAt(15), 10);
717
+ for (var index = 0; index < toCheckAccount.length; index++) {
718
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
719
+ }
720
+ var remainder_1 = sum % 10;
721
+ return controlDigitAccount === (remainder_1 === 0 ? 0 : 10 - remainder_1);
722
+ }
723
+ else {
724
+ var toCheckAccount = bban.substring(8, 23);
725
+ var controlDigitAccount = parseInt(bban.charAt(23), 10);
726
+ for (var index = 0; index < toCheckAccount.length; index++) {
727
+ sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];
728
+ }
729
+ var remainder_2 = sum % 10;
730
+ return controlDigitAccount === (remainder_2 === 0 ? 0 : 10 - remainder_2);
731
+ }
732
+ };
534
733
  /**
535
734
  * Country specifications
536
735
  */
@@ -568,6 +767,7 @@ export var countrySpecs = {
568
767
  AX: {
569
768
  chars: 18,
570
769
  bban_regexp: '^[0-9]{14}$',
770
+ bban_validation_func: checkFinlandBBAN,
571
771
  IBANRegistry: true,
572
772
  },
573
773
  AZ: {
@@ -675,7 +875,13 @@ export var countrySpecs = {
675
875
  IBANRegistry: true,
676
876
  SEPA: true,
677
877
  },
678
- CZ: { chars: 24, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
878
+ CZ: {
879
+ chars: 24,
880
+ bban_regexp: '^[0-9]{20}$',
881
+ bban_validation_func: checkCzechBBAN,
882
+ IBANRegistry: true,
883
+ SEPA: true,
884
+ },
679
885
  DE: { chars: 22, bban_regexp: '^[0-9]{18}$', IBANRegistry: true, SEPA: true },
680
886
  DJ: {
681
887
  chars: 27,
@@ -693,13 +899,31 @@ export var countrySpecs = {
693
899
  bban_regexp: '^[0-9]{22}$',
694
900
  },
695
901
  EC: {},
696
- EE: { chars: 20, bban_regexp: '^[0-9]{16}$', IBANRegistry: true, SEPA: true },
902
+ EE: {
903
+ chars: 20,
904
+ bban_regexp: '^[0-9]{16}$',
905
+ bban_validation_func: checkEstonianBBAN,
906
+ IBANRegistry: true,
907
+ SEPA: true,
908
+ },
697
909
  EG: { chars: 29, bban_regexp: '^[0-9]{25}', IBANRegistry: true },
698
910
  EH: {},
699
911
  ER: {},
700
- ES: { chars: 24, bban_validation_func: checkSpainBBAN, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true },
912
+ ES: {
913
+ chars: 24,
914
+ bban_validation_func: checkSpainBBAN,
915
+ bban_regexp: '^[0-9]{20}$',
916
+ IBANRegistry: true,
917
+ SEPA: true,
918
+ },
701
919
  ET: {},
702
- FI: { chars: 18, bban_regexp: '^[0-9]{14}$', IBANRegistry: true, SEPA: true },
920
+ FI: {
921
+ chars: 18,
922
+ bban_regexp: '^[0-9]{14}$',
923
+ bban_validation_func: checkFinlandBBAN,
924
+ IBANRegistry: true,
925
+ SEPA: true,
926
+ },
703
927
  FJ: {},
704
928
  FK: {},
705
929
  FM: {},
@@ -707,6 +931,7 @@ export var countrySpecs = {
707
931
  FR: {
708
932
  chars: 27,
709
933
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
934
+ bban_validation_func: checkFrenchBBAN,
710
935
  IBANRegistry: true,
711
936
  SEPA: true,
712
937
  },
@@ -775,9 +1000,21 @@ export var countrySpecs = {
775
1000
  chars: 28,
776
1001
  bban_regexp: '^[A-Z]{4}[0-9]{20}$',
777
1002
  },
778
- HR: { chars: 21, bban_regexp: '^[0-9]{17}$', IBANRegistry: true, SEPA: true },
1003
+ HR: {
1004
+ chars: 21,
1005
+ bban_regexp: '^[0-9]{17}$',
1006
+ bban_validation_func: checkCroatianBBAN,
1007
+ IBANRegistry: true,
1008
+ SEPA: true,
1009
+ },
779
1010
  HT: {},
780
- HU: { chars: 28, bban_regexp: '^[0-9]{24}$', IBANRegistry: true, SEPA: true },
1011
+ HU: {
1012
+ chars: 28,
1013
+ bban_regexp: '^[0-9]{24}$',
1014
+ bban_validation_func: checkHungarianBBAN,
1015
+ IBANRegistry: true,
1016
+ SEPA: true,
1017
+ },
781
1018
  ID: {},
782
1019
  IE: {
783
1020
  chars: 22,
@@ -884,6 +1121,7 @@ export var countrySpecs = {
884
1121
  MC: {
885
1122
  chars: 27,
886
1123
  bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',
1124
+ bban_validation_func: checkFrenchBBAN,
887
1125
  IBANRegistry: true,
888
1126
  SEPA: true,
889
1127
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ibantools",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
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",