Browse Source

#232: Validate Romanian numerical personal code (CNP)

phuoc 11 years ago
parent
commit
73743d7845
3 changed files with 141 additions and 26 deletions
  1. 81 18
      dist/js/bootstrapValidator.js
  2. 2 2
      dist/js/bootstrapValidator.min.js
  3. 58 6
      src/js/validator/id.js

+ 81 - 18
dist/js/bootstrapValidator.js

@@ -852,6 +852,28 @@
     // Helper methods, which can be used in validator class
     $.fn.bootstrapValidator.helpers = {
         /**
+         * Validate a date
+         *
+         * @param {Number} year The full year in 4 digits
+         * @param {Number} month The month number
+         * @param {Number} day The day number
+         * @returns {Boolean}
+         */
+        date: function(year, month, day) {
+            if (year < 1000 || year > 9999 || month == 0 || month > 12) {
+                return false;
+            }
+            var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+            // Update the number of days in Feb of leap year
+            if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
+                numDays[1] = 29;
+            }
+
+            // Check the day
+            return (day > 0 && day <= numDays[month - 1]);
+        },
+
+        /**
          * Implement Luhn validation algorithm ((http://en.wikipedia.org/wiki/Luhn))
          * Credit to https://gist.github.com/ShirtlessKirk/2134376
          *
@@ -1343,18 +1365,7 @@
             month = parseInt(month, 10);
             year  = parseInt(year, 10);
 
-            if (year < 1000 || year > 9999 || month == 0 || month > 12) {
-                return false;
-            }
-
-            var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-            // Update the number of days in Feb of leap year
-            if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
-                numDays[1] = 29;
-            }
-
-            // Check the day
-            return (day > 0 && day <= numDays[month - 1]);
+            return $.fn.bootstrapValidator.helpers.date(year, month, day);
         }
     };
 }(window.jQuery));
@@ -1947,9 +1958,7 @@
                 month -= 20;
             }
 
-            try {
-                var d = new Date(year, month, day);
-            } catch (ex) {
+            if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
                 return false;
             }
 
@@ -2032,9 +2041,7 @@
                 year += 100;
             }
 
-            try {
-                var d = new Date(year, month, day);
-            } catch (ex) {
+            if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
                 return false;
             }
 
@@ -2097,6 +2104,62 @@
                 return false;
             }
             return $.fn.bootstrapValidator.helpers.mod_11_10(value);
+        },
+
+        /**
+         * Validate Romanian numerical personal code (CNP)
+         * Examples:
+         * - Valid: 1630615123457, 1800101221144
+         * - Invalid: 8800101221144, 1632215123457, 1630615123458
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Romania
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _ro: function(value) {
+            if (!/^[0-9]{13}$/.test(value)) {
+                return false;
+            }
+            var gender = parseInt(value.charAt(0));
+            if (gender == 0 || gender == 7 || gender == 8) {
+                return false;
+            }
+
+            // Determine the date of birth
+            var year      = parseInt(value.substr(1, 2), 10),
+                month     = parseInt(value.substr(3, 2), 10),
+                day       = parseInt(value.substr(5, 2), 10),
+                // The year of date is determined base on the gender
+                centuries = {
+                    '1': 1900,  // Male born between 1900 and 1999
+                    '2': 1900,  // Female born between 1900 and 1999
+                    '3': 1800,  // Male born between 1800 and 1899
+                    '4': 1800,  // Female born between 1800 and 1899
+                    '5': 2000,  // Male born after 2000
+                    '6': 2000   // Female born after 2000
+                };
+            if (day > 31 && month > 12) {
+                return false;
+            }
+            if (gender != 9) {
+                year = centuries[gender + ''] + year;
+                if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
+                    return false;
+                }
+            }
+
+            // Validate the check digit
+            var sum    = 0,
+                weight = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9],
+                length = value.length;
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i)) * weight[i];
+            }
+            sum = sum % 11;
+            if (sum == 10) {
+                sum = 1;
+            }
+            return (sum == value.charAt(length - 1));
         }
     };
 }(window.jQuery));

File diff suppressed because it is too large
+ 2 - 2
dist/js/bootstrapValidator.min.js


+ 58 - 6
src/js/validator/id.js

@@ -148,9 +148,7 @@
                 month -= 20;
             }
 
-            try {
-                var d = new Date(year, month, day);
-            } catch (ex) {
+            if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
                 return false;
             }
 
@@ -233,9 +231,7 @@
                 year += 100;
             }
 
-            try {
-                var d = new Date(year, month, day);
-            } catch (ex) {
+            if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
                 return false;
             }
 
@@ -298,6 +294,62 @@
                 return false;
             }
             return $.fn.bootstrapValidator.helpers.mod_11_10(value);
+        },
+
+        /**
+         * Validate Romanian numerical personal code (CNP)
+         * Examples:
+         * - Valid: 1630615123457, 1800101221144
+         * - Invalid: 8800101221144, 1632215123457, 1630615123458
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Romania
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _ro: function(value) {
+            if (!/^[0-9]{13}$/.test(value)) {
+                return false;
+            }
+            var gender = parseInt(value.charAt(0));
+            if (gender == 0 || gender == 7 || gender == 8) {
+                return false;
+            }
+
+            // Determine the date of birth
+            var year      = parseInt(value.substr(1, 2), 10),
+                month     = parseInt(value.substr(3, 2), 10),
+                day       = parseInt(value.substr(5, 2), 10),
+                // The year of date is determined base on the gender
+                centuries = {
+                    '1': 1900,  // Male born between 1900 and 1999
+                    '2': 1900,  // Female born between 1900 and 1999
+                    '3': 1800,  // Male born between 1800 and 1899
+                    '4': 1800,  // Female born between 1800 and 1899
+                    '5': 2000,  // Male born after 2000
+                    '6': 2000   // Female born after 2000
+                };
+            if (day > 31 && month > 12) {
+                return false;
+            }
+            if (gender != 9) {
+                year = centuries[gender + ''] + year;
+                if (!$.fn.bootstrapValidator.helpers.date(year, month, day)) {
+                    return false;
+                }
+            }
+
+            // Validate the check digit
+            var sum    = 0,
+                weight = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9],
+                length = value.length;
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i)) * weight[i];
+            }
+            sum = sum % 11;
+            if (sum == 10) {
+                sum = 1;
+            }
+            return (sum == value.charAt(length - 1));
         }
     };
 }(window.jQuery));