kennitala
Advanced tools
Comparing version 2.0.0-beta.2 to 2.0.0-beta.3
declare module "kennitala" { | ||
export function isValid(kennitala: string | number): boolean; | ||
export function isPerson(kennitala: string | number): boolean; | ||
export function isCompany(kennitala: string | number): boolean; | ||
export function isValid(kennitala: string): boolean; | ||
export function isPerson(kennitala: string): boolean; | ||
export function isCompany(kennitala: string): boolean; | ||
export function isTemporary(kennitala: string): boolean; | ||
export function sanitize(kennitala: string | number): string; | ||
export function format(kennitala: string | number, spacer?: string): string; | ||
export function sanitize(kennitala: string): string | undefined; | ||
export function format(kennitala: string, spacer?: string): string; | ||
export function generatePerson(date: Date): string | ||
export function generatePerson(date: Date, startingIncrement: number): string | undefined; | ||
export function generateCompany(date: Date): string; | ||
export function generatePerson(date: Date): string; | ||
export function generatePerson( | ||
date: Date, | ||
startingIncrement: number | ||
): string | undefined; | ||
export function generateCompany(date: Date): string; | ||
export function info(kennitala: string | number): KennitalaInfo; | ||
export function info(kennitala: string): KennitalaInfo; | ||
export interface KennitalaInfo { | ||
kt: string; | ||
valid: boolean; | ||
type: "person" | "company"; | ||
birthday: Date; | ||
birthdayReadable: string; | ||
age: number; | ||
} | ||
export interface KennitalaInfo { | ||
kt: string; | ||
valid: boolean; | ||
type: "person" | "company"; | ||
birthday: Date; | ||
birthdayReadable: string; | ||
age: number; | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
!function(){function r(r,n){var t=s(r);if(10!==t.length)return!1;if(n&&!n(t))return!1;var e=t.split("").reduce(function(r,n,t){return r+n*f[t]},0),a=11-e%11,i=parseInt(t.substring(8,9),10);return 11==a&&0===i||a===i}function n(r){var n=s(r),t=parseInt(n.substring(0,2),10),e=parseInt(n.substring(2,4),10),a=parseInt(n.substring(4,6),10),i=parseInt(n.substring(9,10),10),u="";if(isNaN(t)||isNaN(e)||isNaN(a)||isNaN(i))return!1;t>40&&t<=71&&(t-=40),0===i?u="20":9===i?u="19":8===i&&(u="18");var o=u;return o+=a<10?"0"+a:""+a,o+="-",o+=e<10?"0"+e:""+e,o+="-",o+=t<10?"0"+t:""+t,!isNaN(new Date(o).getTime())}function t(r){var n=s(r),t=parseInt(n.substring(0,2),10);return t>0&&t<=31}function e(r){var n=s(r),t=parseInt(n.substring(0,2),10);return t>40&&t<=71}function a(r,n,e){function a(r){var n=""+Math.floor(10*Math.random()),e=""+Math.floor(10*Math.random());t(r)&&(n=""+Math.floor(8*Math.random()+2));for(var i=r+n+e,u=0,s=0;s<8;s++)u+=i[s]*f[s];return u=11-u%11,u=11==u?0:u,10==u?a(r):n+e+u}function i(r,n){var t=parseInt(n,10);if(!(t>=100||isNaN(t))){for(var e=t.toString().split(""),a=e[0],u=e[1],s=r+a+u,o=0,g=0;g<8;g++)o+=s[g]*f[g];return o=11-o%11,o=11==o?0:o,10==o?i(r,t+1):a+u+o}}var u="",s=r.getDate();s<10&&(s="0"+s),s=""+s,s=n(s),u+=s;var o=r.getMonth();o+=1,o<10&&(o="0"+o),o=""+o,u+=o;var g=r.getFullYear();if(g=""+g,g=g[2]+g[3],u+=g,"number"==typeof e){var v=i(u,e);if(void 0===v)return;u+=v}else u+=a(u);return g=r.getFullYear(),g=""+g,u+=g[1]}function i(r){return r}function u(r){return""+(parseInt(r,10)+40)}function s(r){var n=""+r;return n=n.replace(/(\D)+/g,"")}var o={};o.isValid=function(a){var i=s(a);if(10===i.length&&("8"===i.substring(0,1)||"9"===i.substring(0,1)))return!0;var u=r(a,t),o=r(a,e);return n(a)&&(u||o)},o.isPerson=function(e){return n(e)&&r(e,t)},o.isCompany=function(t){return n(t)&&r(t,e)},o.isTemporary=function(r){var n=s(r);return 10===n.length&&("8"===n.substring(0,1)||"9"===n.substring(0,1))},o.sanitize=function(r){return s(r)},o.format=function(r,n){var t=s(r);return n=void 0!==n?n:"-",t.substring(0,6)+n+t.substring(6,10)},o.generatePerson=function(r,n){return a(r,i,n)},o.generateCompany=function(r){return a(r,u)},o.info=function(n){var a={};a.kt=s(n);var i=r(n,t),u=r(n,e);if(i||u){a.valid=!0,a.type=!0===i?"person":"company";var o=s(n),f=o.substring(0,2);f>31&&(f-=40);var g=o.substring(2,4),v=(0==o.substring(9,10)?20:19)+o.substring(4,6),l=new Date(v,g-1,f);a.birthday=l,a.birthdayReadable=l.toDateString();var c=new Date,d=c.getFullYear(),p=new Date(l);p.setFullYear(d);var b=d-l.getFullYear();return p>c&&b--,b<0?b+=100:b=b<1?(c.getTime()-l.getTime())/1e3/60/60/24/365.2422:b,a.age=b,a}return a.valid=!1,a};var f=[3,2,7,6,5,4,3,2,0,0];"undefined"!=typeof module&&module.exports?module.exports=o:"function"==typeof define&&define.amd?define(o):window&&(window.kennitala=o)}(); | ||
!function(){function r(r,t){var n=o(r);if(10!==n.length||t&&!t(n))return!1;var e=n.split("").reduce(function(r,t,n){return r+t*g[n]},0),a=11-e%11,i=parseInt(n.substring(8,9),10);return 11==a&&0===i||a===i}function t(r){var t=parseInt(r.substring(0,2),10),n=parseInt(r.substring(2,4),10),e=parseInt(r.substring(4,6),10),a=parseInt(r.substring(9,10),10),i="";if(isNaN(t)||isNaN(n)||isNaN(e)||isNaN(a))return!1;t>40&&t<=71&&(t-=40),0===a?i="20":9===a?i="19":8===a&&(i="18");var u=i;return u+=e<10?"0"+e:""+e,u+="-",u+=n<10?"0"+n:""+n,u+="-",u+=t<10?"0"+t:""+t,!isNaN(new Date(u).getTime())}function n(r){var t=parseInt(r.substring(0,2),10),n=parseInt(r.substring(6,8));return t>0&&t<=31&&n>=20}function e(r){var t=parseInt(r.substring(0,2),10),n=r.substring(6,8);return t>0&&t<=31&&("14"===n||"15"===n)}function a(r){var t=parseInt(r.substring(0,2),10);return t>40&&t<=71}function i(r,t,e){function a(r){var t=""+Math.floor(10*Math.random()),e=""+Math.floor(10*Math.random());n(r)&&(t=""+Math.floor(8*Math.random()+2));for(var i=r+t+e,u=0,s=0;s<8;s++)u+=i[s]*g[s];return u=11-u%11,u=11==u?0:u,10==u?a(r):t+e+u}function i(r,t){var n=parseInt(t,10);if(!(n>=100||isNaN(n))){for(var e=n.toString().split(""),a=e[0],u=e[1],s=r+a+u,o=0,f=0;f<8;f++)o+=s[f]*g[f];return o=11-o%11,o=11==o?0:o,10==o?i(r,n+1):a+u+o}}var u="",s=r.getDate();s<10&&(s="0"+s),s=""+s,s=t(s),u+=s;var o=r.getMonth();o+=1,o<10&&(o="0"+o),o=""+o,u+=o;var f=r.getFullYear();if(f=""+f,f=f[2]+f[3],u+=f,"number"==typeof e){var v=i(u,e);if(void 0===v)return;u+=v}else u+=a(u);return f=r.getFullYear(),f=""+f,u+=f[1]}function u(r){return r}function s(r){return""+(parseInt(r,10)+40)}function o(r){return"string"==typeof r&&r.match(/^\d{6}-?\d{4}$/)?r.replace(/\D+/g,""):void 0}function f(r){return{allowTestDataset:!!r&&!0===r.allowTestDataset}}var v={};v.isValid=function(i,u){var s=f(u),v=o(i);if(void 0===v)return!1;if(10===v.length&&("8"===v.substring(0,1)||"9"===v.substring(0,1)))return!0;var g=r(v,n),l=r(v,e),d=r(v,a);return t(v)&&(g||d||l&&s.allowTestDataset)},v.isPerson=function(a,i){var u=f(i),s=o(a);if(void 0===s)return!1;var v=t(s);return e(s)&&u.allowTestDataset?v&&r(a,e):v&&r(a,n)},v.isCompany=function(n){var e=o(n);return void 0!==e&&(t(e)&&r(n,a))},v.isTemporary=function(r){var t=o(r);return void 0!==t&&(10===t.length&&("8"===t.substring(0,1)||"9"===t.substring(0,1)))},v.sanitize=function(r){return o(r)},v.format=function(r,t){var n=r.replace(/(\D)+/g,"");return t=void 0!==t?t:"-",n.substring(0,6)+t+n.substring(6,10)},v.generatePerson=function(r,t){return i(r,u,t)},v.generateCompany=function(r){return i(r,s)},v.info=function(t){var e={},i=o(t);if(void 0===i)return e.valid=!1,e;e.kt=i;var u=r(i,n),s=r(i,a);if(u||s){e.valid=!0,e.type=!0===u?"person":"company";var t=o(i),f=t.substring(0,2);f>31&&(f-=40);var v=t.substring(2,4),g=(0==t.substring(9,10)?20:19)+t.substring(4,6),l=new Date(g,v-1,f);e.birthday=l,e.birthdayReadable=l.toDateString();var d=new Date,c=d.getFullYear(),p=new Date(l);p.setFullYear(c);var b=c-l.getFullYear();return p>d&&b--,b<0?b+=100:b=b<1?(d.getTime()-l.getTime())/1e3/60/60/24/365.2422:b,e.age=b,e}return e.valid=!1,e};var g=[3,2,7,6,5,4,3,2,0,0];"undefined"!=typeof module&&module.exports?module.exports=v:"function"==typeof define&&define.amd?define(v):window&&(window.kennitala=v)}(); | ||
//# sourceMappingURL=kennitala.min.js.map |
595
kennitala.js
@@ -1,61 +0,99 @@ | ||
(function(){ | ||
/* | ||
(function () { | ||
/* | ||
Library API exports | ||
*/ | ||
var kennitala = {}; | ||
var kennitala = {}; | ||
kennitala.isValid = function(kennitala) { | ||
// Adds support for temporary KT | ||
var kt = sanitizeInput(kennitala); | ||
kennitala.isValid = function (kennitala, options) { | ||
// Default options | ||
var opts = getDefaultOptions(options); | ||
if (kt.length === 10 && (kt.substring(0, 1) === '8' || kt.substring(0, 1) === '9')) { | ||
return true; | ||
} | ||
// Checks format is valid | ||
var kt = sanitizeInput(kennitala); | ||
if (kt === undefined) { | ||
return false; | ||
} | ||
var person = evaluate(kennitala, isPerson); | ||
var company = evaluate(kennitala, isCompany); | ||
var dateValid = isValidDate(kennitala) | ||
// Checks if ID is a temporary ID, if so return true | ||
if ( | ||
kt.length === 10 && | ||
(kt.substring(0, 1) === "8" || kt.substring(0, 1) === "9") | ||
) { | ||
return true; | ||
} | ||
return dateValid && (person || company); | ||
var person = evaluate(kt, isPerson); | ||
var testPerson = evaluate(kt, isTestPerson); | ||
var company = evaluate(kt, isCompany); | ||
var dateValid = isValidDate(kt); | ||
return ( | ||
dateValid && (person || company || (testPerson && opts.allowTestDataset)) | ||
); | ||
}; | ||
kennitala.isPerson = function (kennitala, options) { | ||
// Default options | ||
var opts = getDefaultOptions(options); | ||
// Checks format is valid | ||
var kt = sanitizeInput(kennitala); | ||
if (kt === undefined) { | ||
return false; | ||
} | ||
kennitala.isPerson = function(kennitala) { | ||
var dateValid = isValidDate(kennitala) | ||
var dateValid = isValidDate(kt); | ||
return dateValid && evaluate(kennitala, isPerson); | ||
}; | ||
if (isTestPerson(kt) && opts.allowTestDataset) { | ||
return dateValid && evaluate(kennitala, isTestPerson); | ||
} else { | ||
return dateValid && evaluate(kennitala, isPerson); | ||
} | ||
}; | ||
kennitala.isCompany = function(kennitala) { | ||
var dateValid = isValidDate(kennitala) | ||
kennitala.isCompany = function (kennitala) { | ||
var kt = sanitizeInput(kennitala); | ||
if (kt === undefined) { | ||
return false; | ||
} | ||
return dateValid && evaluate(kennitala, isCompany); | ||
}; | ||
var dateValid = isValidDate(kt); | ||
kennitala.isTemporary = function(kennitala) { | ||
var kt = sanitizeInput(kennitala) | ||
return dateValid && evaluate(kennitala, isCompany); | ||
}; | ||
return (kt.length === 10 && (kt.substring(0, 1) === '8' || kt.substring(0, 1) === '9')); | ||
kennitala.isTemporary = function (kennitala) { | ||
var kt = sanitizeInput(kennitala); | ||
if (kt === undefined) { | ||
return false; | ||
} | ||
kennitala.sanitize = function (kennitala) { | ||
return sanitizeInput(kennitala); | ||
}; | ||
return ( | ||
kt.length === 10 && | ||
(kt.substring(0, 1) === "8" || kt.substring(0, 1) === "9") | ||
); | ||
}; | ||
kennitala.format = function (kennitala, spacer) { | ||
var kt = sanitizeInput(kennitala); | ||
spacer = spacer !== undefined ? spacer : '-'; | ||
// Useful for sanitizing inputs before storing in database etc... | ||
kennitala.sanitize = function (kennitala) { | ||
return sanitizeInput(kennitala); | ||
}; | ||
return kt.substring(0,6) + spacer + kt.substring(6, 10); | ||
}; | ||
// Useful for formating inputs in forms not meant for sanitizing or validating | ||
kennitala.format = function (kennitala, spacer) { | ||
var kt = kennitala.replace(/(\D)+/g, ""); | ||
spacer = spacer !== undefined ? spacer : "-"; | ||
kennitala.generatePerson = function(date, startingIncrement) { | ||
return generateKennitala(date, personDayDelta, startingIncrement); | ||
}; | ||
return kt.substring(0, 6) + spacer + kt.substring(6, 10); | ||
}; | ||
kennitala.generateCompany = function(date) { | ||
return generateKennitala(date, companyDayDelta); | ||
}; | ||
kennitala.generatePerson = function (date, startingIncrement) { | ||
return generateKennitala(date, personDayDelta, startingIncrement); | ||
}; | ||
/* | ||
kennitala.generateCompany = function (date) { | ||
return generateKennitala(date, companyDayDelta); | ||
}; | ||
/* | ||
Returns object with relevant information about kennitala | ||
@@ -71,184 +109,193 @@ { | ||
*/ | ||
kennitala.info = function(kt){ | ||
var info = {}; | ||
kennitala.info = function (kennitala) { | ||
var info = {}; | ||
var kt = sanitizeInput(kennitala); | ||
info.kt = sanitizeInput(kt); | ||
if (kt === undefined) { | ||
info.valid = false; | ||
var isPersonType = evaluate(kt, isPerson); | ||
var isCompanyType = evaluate(kt, isCompany); | ||
return info; | ||
} | ||
// Check if kennitala is a valid company or person | ||
if (isPersonType || isCompanyType){ | ||
info.valid = true; | ||
info.type = isPersonType === true ? "person" : "company"; | ||
info.kt = kt; | ||
// Get birthday Date object | ||
var kennitala = sanitizeInput(kt); | ||
var day = kennitala.substring(0, 2); | ||
// Company day delta | ||
if (day > 31) { | ||
day = day - 40; | ||
} | ||
var month = kennitala.substring(2, 4); | ||
var isPersonType = evaluate(kt, isPerson); | ||
var isCompanyType = evaluate(kt, isCompany); | ||
// Century | ||
var year = (kennitala.substring(9, 10) == 0 ? 20 : 19) + kennitala.substring(4, 6); | ||
var birthday = new Date(year, month - 1, day); | ||
info.birthday = birthday; | ||
// Check if kennitala is a valid company or person | ||
if (isPersonType || isCompanyType) { | ||
info.valid = true; | ||
info.type = isPersonType === true ? "person" : "company"; | ||
// Birthday readable string | ||
info.birthdayReadable = birthday.toDateString(); | ||
// Get birthday Date object | ||
var kennitala = sanitizeInput(kt); | ||
var day = kennitala.substring(0, 2); | ||
// Age | ||
var today = new Date(); | ||
var currentYear = today.getFullYear(); | ||
// Birthday shifted forward to the current year | ||
var calcDate = new Date(birthday); | ||
calcDate.setFullYear(currentYear); | ||
var age = currentYear - birthday.getFullYear(); | ||
if (calcDate > today) { | ||
age--; | ||
} | ||
if (age < 0) { | ||
// þjóðskrá some times registers kennitölur with temporary last digits... add 100 to correct negative age outcome | ||
age = age + 100; | ||
} | ||
else { | ||
age = age < 1 | ||
? (today.getTime() - birthday.getTime()) / | ||
1000 / | ||
60 / | ||
60 / | ||
24 / | ||
365.2422 | ||
: age; | ||
} | ||
// Company day delta | ||
if (day > 31) { | ||
day = day - 40; | ||
} | ||
var month = kennitala.substring(2, 4); | ||
info.age = age; | ||
// Century | ||
var year = | ||
(kennitala.substring(9, 10) == 0 ? 20 : 19) + kennitala.substring(4, 6); | ||
var birthday = new Date(year, month - 1, day); | ||
info.birthday = birthday; | ||
return info; | ||
} | ||
else { | ||
info.valid = false; | ||
return info; | ||
} | ||
} | ||
// Birthday readable string | ||
info.birthdayReadable = birthday.toDateString(); | ||
/** | ||
* Evaluates the input string as a possible kennitala, as well | ||
* as running the possible entityEvaluation function on the input, | ||
* before calculating the sum | ||
*/ | ||
var MAGIC_NUMBERS = [3, 2, 7, 6, 5, 4, 3, 2, 0, 0]; | ||
function evaluate(input, entityEvaluationFn) { | ||
var kt = sanitizeInput(input); | ||
if (kt.length !== 10) { | ||
return false; | ||
} | ||
// Age | ||
var today = new Date(); | ||
var currentYear = today.getFullYear(); | ||
if (entityEvaluationFn && !entityEvaluationFn(kt)) { | ||
return false; | ||
} | ||
var sum = kt.split('').reduce(function (prev, curr, i) { | ||
return prev + curr * MAGIC_NUMBERS[i]; | ||
}, 0); | ||
// Birthday shifted forward to the current year | ||
var calcDate = new Date(birthday); | ||
calcDate.setFullYear(currentYear); | ||
var remainder = 11 - (sum % 11); | ||
var secretNr = parseInt(kt.substring(8, 9), 10); | ||
var age = currentYear - birthday.getFullYear(); | ||
if (calcDate > today) { | ||
age--; | ||
} | ||
if (age < 0) { | ||
// þjóðskrá some times registers kennitölur with temporary last digits... add 100 to correct negative age outcome | ||
age = age + 100; | ||
} else { | ||
age = | ||
age < 1 | ||
? (today.getTime() - birthday.getTime()) / | ||
1000 / | ||
60 / | ||
60 / | ||
24 / | ||
365.2422 | ||
: age; | ||
} | ||
return (remainder == 11 && secretNr === 0) || remainder === secretNr; | ||
info.age = age; | ||
return info; | ||
} else { | ||
info.valid = false; | ||
return info; | ||
} | ||
}; | ||
// Checks if date is valid. This function could probably be simplified. | ||
function isValidDate(kennitala) { | ||
var kt = sanitizeInput(kennitala) | ||
/** | ||
* Evaluates the input string as a possible kennitala, as well | ||
* as running the possible entityEvaluation function on the input, | ||
* before calculating the sum | ||
*/ | ||
var MAGIC_NUMBERS = [3, 2, 7, 6, 5, 4, 3, 2, 0, 0]; | ||
function evaluate(input, entityEvaluationFn) { | ||
var kt = sanitizeInput(input); | ||
if (kt.length !== 10 || (entityEvaluationFn && !entityEvaluationFn(kt))) { | ||
return false; | ||
} | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
var m = parseInt(kt.substring(2, 4), 10); | ||
var y = parseInt(kt.substring(4, 6), 10); | ||
var c = parseInt(kt.substring(9, 10), 10); | ||
var yPre = "" | ||
var sum = kt.split("").reduce(function (prev, curr, i) { | ||
return prev + curr * MAGIC_NUMBERS[i]; | ||
}, 0); | ||
if (isNaN(d) || isNaN(m) || isNaN(y) || isNaN(c)) { | ||
return false; | ||
} | ||
var remainder = 11 - (sum % 11); | ||
var secretNr = parseInt(kt.substring(8, 9), 10); | ||
// For company kt we remove 40 from day | ||
if (d > 40 && d <= 71) { | ||
d = d - 40; | ||
} | ||
return (remainder == 11 && secretNr === 0) || remainder === secretNr; | ||
} | ||
if (c === 0) { | ||
yPre = "20" | ||
} else if (c === 9) { | ||
yPre = "19" | ||
} else if (c === 8) { | ||
yPre = "18" | ||
} | ||
// Checks if date is valid. This function could probably be simplified. | ||
function isValidDate(kt) { | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
var m = parseInt(kt.substring(2, 4), 10); | ||
var y = parseInt(kt.substring(4, 6), 10); | ||
var c = parseInt(kt.substring(9, 10), 10); | ||
var yPre = ""; | ||
var date = yPre | ||
date += (y < 10) ? "0" + y : "" + y | ||
date += "-" | ||
date += (m < 10) ? "0" + m : "" + m | ||
date += "-" | ||
date += (d < 10) ? "0" + d : "" + d | ||
if (isNaN(d) || isNaN(m) || isNaN(y) || isNaN(c)) { | ||
return false; | ||
} | ||
return !isNaN(new Date(date).getTime()) | ||
// For company kt we remove 40 from day | ||
if (d > 40 && d <= 71) { | ||
d = d - 40; | ||
} | ||
// People have first two characters between 1-31 | ||
function isPerson(kennitala) { | ||
var kt = sanitizeInput(kennitala) | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
return d > 0 && d <= 31; | ||
if (c === 0) { | ||
yPre = "20"; | ||
} else if (c === 9) { | ||
yPre = "19"; | ||
} else if (c === 8) { | ||
yPre = "18"; | ||
} | ||
// Companies have first two characters between 41-71 | ||
function isCompany(kennitala) { | ||
var kt = sanitizeInput(kennitala) | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
var date = yPre; | ||
date += y < 10 ? "0" + y : "" + y; | ||
date += "-"; | ||
date += m < 10 ? "0" + m : "" + m; | ||
date += "-"; | ||
date += d < 10 ? "0" + d : "" + d; | ||
return d > 40 && d <= 71; | ||
} | ||
return !isNaN(new Date(date).getTime()); | ||
} | ||
// Generate kennitala, takes in person/company entity function as well | ||
function generateKennitala(date, entityFn, startingIncrement) { | ||
var kt = ''; | ||
// People have first two characters between 1-31 and 7-8th characters >= 20 | ||
function isPerson(kt) { | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
var digits78 = parseInt(kt.substring(6, 8)); | ||
// Date of month | ||
var day = date.getDate(); | ||
if (day < 10) { | ||
day = "0"+day; | ||
} | ||
day = ""+day; | ||
return d > 0 && d <= 31 && digits78 >= 20; | ||
} | ||
// Raise the day by 0 or 40 depending on whether this is a person or company | ||
day = entityFn(day); | ||
// Test people have first two characters between 1-31 and 7-8th characters of 14 or 15 | ||
function isTestPerson(kt) { | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
var digits78 = kt.substring(6, 8); | ||
kt += day; | ||
return d > 0 && d <= 31 && (digits78 === "14" || digits78 === "15"); | ||
} | ||
// Month | ||
var month = date.getMonth(); | ||
month += 1; | ||
// Companies have first two characters between 41-71 | ||
function isCompany(kt) { | ||
var d = parseInt(kt.substring(0, 2), 10); | ||
if (month < 10) { | ||
month = "0"+month; | ||
} | ||
month = ""+month; | ||
return d > 40 && d <= 71; | ||
} | ||
kt += month; | ||
// Generate kennitala, takes in person/company entity function as well | ||
function generateKennitala(date, entityFn, startingIncrement) { | ||
var kt = ""; | ||
// Year | ||
var year = date.getFullYear(); | ||
year = ""+year; | ||
year = year[2] + year[3]; | ||
// Date of month | ||
var day = date.getDate(); | ||
if (day < 10) { | ||
day = "0" + day; | ||
} | ||
day = "" + day; | ||
kt += year; | ||
// Raise the day by 0 or 40 depending on whether this is a person or company | ||
day = entityFn(day); | ||
/* | ||
kt += day; | ||
// Month | ||
var month = date.getMonth(); | ||
month += 1; | ||
if (month < 10) { | ||
month = "0" + month; | ||
} | ||
month = "" + month; | ||
kt += month; | ||
// Year | ||
var year = date.getFullYear(); | ||
year = "" + year; | ||
year = year[2] + year[3]; | ||
kt += year; | ||
/* | ||
Recursive function that generates two random digits | ||
@@ -259,34 +306,33 @@ then generates 9th character from 1-8th characters | ||
*/ | ||
function randomAndChecksum(kt) { | ||
/* | ||
function randomAndChecksum(kt) { | ||
/* | ||
7th and 8th characters are seemingly random for companies | ||
but are incrementing from 20-99 for individuals | ||
*/ | ||
var digit7 = "" + Math.floor(Math.random() * 10); | ||
var digit8 = "" + Math.floor(Math.random() * 10); | ||
var digit7 = "" + Math.floor(Math.random() * 10); | ||
var digit8 = "" + Math.floor(Math.random() * 10); | ||
if (isPerson(kt)) { | ||
digit7 = "" + Math.floor(Math.random() * 8 + 2); | ||
} | ||
if (isPerson(kt)) { | ||
digit7 = "" + Math.floor(Math.random() * 8 + 2); | ||
} | ||
var tempKt = kt + digit7 + digit8; | ||
var tempKt = kt + digit7 + digit8; | ||
// Ninth number | ||
var sum = 0; | ||
for (var i = 0; i < 8; i++) { | ||
sum += tempKt[i] * MAGIC_NUMBERS[i]; | ||
} | ||
// Ninth number | ||
var sum = 0; | ||
for (var i = 0; i < 8; i++) { | ||
sum += tempKt[i] * MAGIC_NUMBERS[i]; | ||
} | ||
sum = 11 - (sum % 11); | ||
sum = (sum == 11) ? 0 : sum; | ||
sum = 11 - (sum % 11); | ||
sum = sum == 11 ? 0 : sum; | ||
if (sum == 10) { | ||
return randomAndChecksum(kt); | ||
} | ||
else{ | ||
return digit7 + digit8 + sum; | ||
} | ||
} | ||
if (sum == 10) { | ||
return randomAndChecksum(kt); | ||
} else { | ||
return digit7 + digit8 + sum; | ||
} | ||
} | ||
/* | ||
/* | ||
Recursive function that generates two digits from the optional starting | ||
@@ -297,87 +343,90 @@ increment parameter then generates 9th character from 1-8th characters | ||
*/ | ||
function incrementingChecksum(kt, incrementFrom) { | ||
/* | ||
function incrementingChecksum(kt, incrementFrom) { | ||
/* | ||
7th and 8th characters are seemingly random for companies | ||
but are incrementing from 20-99 for individuals | ||
*/ | ||
var inc = parseInt(incrementFrom, 10) | ||
if (inc >= 100 || isNaN(inc)) { | ||
return undefined; | ||
} | ||
var inc = parseInt(incrementFrom, 10); | ||
var digits = inc.toString().split(''); | ||
if (inc >= 100 || isNaN(inc)) { | ||
return undefined; | ||
} | ||
var digit7 = digits[0]; | ||
var digit8 = digits[1]; | ||
var digits = inc.toString().split(""); | ||
var tempKt = kt + digit7 + digit8; | ||
var digit7 = digits[0]; | ||
var digit8 = digits[1]; | ||
// Ninth number | ||
var sum = 0; | ||
for (var i = 0; i < 8; i++) { | ||
sum += tempKt[i] * MAGIC_NUMBERS[i]; | ||
} | ||
var tempKt = kt + digit7 + digit8; | ||
sum = 11 - (sum % 11); | ||
sum = (sum == 11) ? 0 : sum; | ||
// Ninth number | ||
var sum = 0; | ||
for (var i = 0; i < 8; i++) { | ||
sum += tempKt[i] * MAGIC_NUMBERS[i]; | ||
} | ||
if (sum == 10) { | ||
return incrementingChecksum(kt, inc+1); | ||
} | ||
else{ | ||
return digit7 + digit8 + sum; | ||
} | ||
} | ||
sum = 11 - (sum % 11); | ||
sum = sum == 11 ? 0 : sum; | ||
if (typeof startingIncrement == 'number') { | ||
var digits789 = incrementingChecksum(kt, startingIncrement) | ||
// If no solution is found return undefined | ||
if (digits789 === undefined) { | ||
return undefined; | ||
} | ||
if (sum == 10) { | ||
return incrementingChecksum(kt, inc + 1); | ||
} else { | ||
return digit7 + digit8 + sum; | ||
} | ||
} | ||
kt += digits789 | ||
} else { | ||
// 7-9th characters | ||
kt += randomAndChecksum(kt); | ||
} | ||
if (typeof startingIncrement == "number") { | ||
var digits789 = incrementingChecksum(kt, startingIncrement); | ||
// 10th character is century | ||
year = date.getFullYear(); | ||
year = ""+year; | ||
kt += year[1]; | ||
// If no solution is found return undefined | ||
if (digits789 === undefined) { | ||
return undefined; | ||
} | ||
return kt; | ||
kt += digits789; | ||
} else { | ||
// 7-9th characters | ||
kt += randomAndChecksum(kt); | ||
} | ||
// People's birth day of month is raised by 0 | ||
function personDayDelta(day){ | ||
return day; | ||
} | ||
// 10th character is century | ||
year = date.getFullYear(); | ||
year = "" + year; | ||
kt += year[1]; | ||
// Companies birth day of month is raised by 40 | ||
function companyDayDelta(day){ | ||
return "" + (parseInt(day, 10) + 40); | ||
} | ||
return kt; | ||
} | ||
// Ensures datatype is string, then removes all non-digit characters from kennitala | ||
function sanitizeInput(p_kennitala) { | ||
var kennitala = "" + p_kennitala; | ||
// People's birth day of month is raised by 0 | ||
function personDayDelta(day) { | ||
return day; | ||
} | ||
kennitala = kennitala.replace(/(\D)+/g, ''); | ||
// Companies birth day of month is raised by 40 | ||
function companyDayDelta(day) { | ||
return "" + (parseInt(day, 10) + 40); | ||
} | ||
return kennitala; | ||
} | ||
// Removes all non-digit characters from kennitala | ||
function sanitizeInput(kennitala) { | ||
// Stricted validation of kennitala in v2, only validate valid strings | ||
return typeof kennitala === "string" && kennitala.match(/^\d{6}-?\d{4}$/) | ||
? kennitala.replace(/\D+/g, "") | ||
: undefined; | ||
} | ||
// UMD wrapper | ||
if (typeof module !== 'undefined' && module.exports) { | ||
module.exports = kennitala; | ||
} else if (typeof define === 'function' && define.amd) { | ||
define(kennitala); | ||
} else if (window) { | ||
window.kennitala = kennitala; | ||
} | ||
function getDefaultOptions(options) { | ||
return { | ||
allowTestDataset: !!options && options.allowTestDataset === true, | ||
}; | ||
} | ||
// UMD wrapper | ||
if (typeof module !== "undefined" && module.exports) { | ||
module.exports = kennitala; | ||
} else if (typeof define === "function" && define.amd) { | ||
define(kennitala); | ||
} else if (window) { | ||
window.kennitala = kennitala; | ||
} | ||
})(); |
{ | ||
"name": "kennitala", | ||
"version": "2.0.0-beta.2", | ||
"version": "2.0.0-beta.3", | ||
"description": "Icelandic social security number (kennitölur) utilities for servers and clients", | ||
@@ -5,0 +5,0 @@ "main": "dist/kennitala.min.js", |
104
README.md
@@ -1,2 +0,5 @@ | ||
<h1 align=left>Kennitala</h1> | ||
Kennitala | ||
--- | ||
Icelandic national ID (kennitölur) utilities for servers and clients. Now with TypeScript support! | ||
@@ -15,13 +18,7 @@ | ||
Install with yarn: | ||
```bash | ||
yarn add kennitala | ||
``` | ||
### Examples | ||
``` Javascript | ||
```Javascript | ||
const kennitala = require('kennitala'); | ||
// Check if kennitala is valid for either a company or individual | ||
@@ -36,3 +33,3 @@ kennitala.isValid('3108962099'); // returns True | ||
This can be done with the included `.clean` or `.format` functions like so: | ||
This can be done with the included `.sanitize` function like so: | ||
@@ -42,3 +39,3 @@ ```Javascript | ||
kennitala.clean('310896DIRTYSSID2099'); | ||
kennitala.sanitize('310896-2099'); | ||
// returns '3108962099' | ||
@@ -49,3 +46,3 @@ ``` | ||
``` Javascript | ||
```Javascript | ||
const kennitala = require('kennitala'); | ||
@@ -56,3 +53,3 @@ | ||
// returns | ||
{ | ||
{ | ||
kt: '3108962099', | ||
@@ -63,3 +60,3 @@ valid: true, | ||
birthdayReadable: 'Sat Aug 31 1996', | ||
age: 22 | ||
age: 27 | ||
} | ||
@@ -69,5 +66,5 @@ | ||
kennitala.isPerson('3108962099'); // returns True | ||
kennitala.isPerson('601010-0890'); // returns False | ||
kennitala.isPerson(3108962099); // returns True | ||
kennitala.isPerson('31^_^08!!96LOL20T_T99'); // returns True | ||
kennitala.isPerson('601010-0890'); // returns False because of invalid date | ||
kennitala.isPerson(3108962099); // returns False because of numeric type | ||
kennitala.isPerson('31^_^08!!96LOL20T_T99'); // returns False because... well, just no | ||
@@ -77,3 +74,3 @@ // Checks if kennitala is valid for a company (returns false for persons) | ||
kennitala.isCompany('601010-0890'); // True | ||
kennitala.isCompany(3108962099); // False | ||
kennitala.isCompany('3108962099'); // False | ||
@@ -84,7 +81,6 @@ // the .format() method formats a kennitala and adds a traditional - spacer | ||
kennitala.format('310896DIRTYSSID2099'); | ||
// returns '310896-2099' | ||
// Great for using with getters/setters in forms where you want to show the traditional format to users | ||
kennitala.format('3108962099', '-apple pie-'); | ||
// returns '310896-apple pie-2099' | ||
kennitala.format('31089620'); | ||
// returns '310896-20' | ||
@@ -94,15 +90,16 @@ kennitala.format('3108962099', ''); | ||
// the .clean() method removes all non digit characters. ideal for database storage | ||
kennitala.clean(3108962099); // returns '3108962099' | ||
``` | ||
### API documentation | ||
kennitala.isValid([string, int]); | ||
kennitala.isValid(string, ?options: { allowTestDataset: false }); | ||
returns boolean | ||
Checks if kennitala checksum is correct for either a person or company | ||
If passed a string with non-digit characters included it removes them before validating | ||
kennitala.info([string, int]); | ||
Allows passing optional options object to enable the test dataset | ||
https://www.skra.is/um-okkur/frettir/frett/2020/10/13/Ny-utgafa-af-gervigognum-thjodskrar/ | ||
kennitala.info(string); | ||
returns object with relevant information about this kennitala | ||
@@ -118,30 +115,34 @@ { | ||
kennitala.isPerson([string, int]); | ||
kennitala.isPerson(string, ?options: { allowTestDataset: false }); | ||
returns boolean | ||
Checks if kennitala checksum is correct and if day of birth is between 1-31 | ||
If passed a string with non-digit characters included it removes them before validating | ||
kennitala.isCompany([string, int]); | ||
Allows passing optional options object to enable the test dataset | ||
https://www.skra.is/um-okkur/frettir/frett/2020/10/13/Ny-utgafa-af-gervigognum-thjodskrar/ | ||
kennitala.isCompany(string); | ||
returns boolean | ||
Checks if kennitala checksum is correct and if day of birth is between 41-71 | ||
If passed a string with non-digit characters included it removes them before validating | ||
kennitala.format([string, int], ?[string]); | ||
kennitala.format(string, ?[string]); | ||
returns string | ||
Ensures datatype is string, then matches and removes all non-digit characters | ||
and adds a traditional '-' spacer between 6th and 7th digit. This can be customized | ||
with an optional 2nd parameter. | ||
kennitala.clean([string, int]); | ||
returns string | ||
kennitala.sanitize(string); | ||
returns string or undefined | ||
Ensures datatype is string, then matches and removes all non-digit characters. | ||
Does not ensure the remaining string is 10 characters or that the kennitala is valid | ||
Does not ensure a valid kennitala, only used for sanitizing input. | ||
kennitala.generatePerson([date]); | ||
returns string | ||
Takes Date object as a parameter and returns a new kennitala for a person | ||
@@ -151,21 +152,12 @@ | ||
returns string | ||
Takes Date object as a parameter and returns a new kennitala for a company | ||
### Testing | ||
### Testing | ||
Uses [Mocha](https://mochajs.org/) for testing. In order to execute the tests, you need to run `npm install -g mocha` first. Once you've done that | ||
Uses [Mocha](https://mochajs.org/) for testing. In order to execute the tests, you need to run `npm install -g mocha` first. Once you've done that | ||
you can open up a command line and point it to the root directory of the project. From there you should be able to type either `npm test` or simply `mocha` to run the tests. | ||
### Building | ||
### Building | ||
To build the project, you can type `npm run dist`, which minifies the script and generates a source map, and places both in the `dist/` folder. | ||
### Sponsored by BrowserStack | ||
Since Oct 2nd 2018 we are proudly sponsored in part by BrowserStack which sponsors thousands of open source projects. The plan is to implement automated testing for older browsers which will give us and our users good overview of the support they can expect for older browsers and operating systems. | ||
<img width=300 src="https://raw.github.com/HermannBjorgvin/Kennitala/master/Browserstack-logo.svg?sanitize=true"> | ||
> I am using BrowserStack to easily test this library accross different browsers and operating systems from the comfort of my personal Linux machines, no need to set up a Windows or MacOS machine for testing. | ||
> - Hermann Björgvin | ||
To build the project, you can type `npm run dist`, which minifies the script and generates a source map, and places both in the `dist/` folder. |
134
test/test.js
@@ -1,67 +0,91 @@ | ||
var kennitala = require('../kennitala.js'); | ||
var should = require('chai').should(); | ||
var kennitala = require("../kennitala.js"); | ||
var should = require("chai").should(); | ||
describe('kennitala', function () { | ||
describe('#isPerson', function () { | ||
it("should validate known valid personal kennitala-s of various formats", function () { | ||
kennitala.isPerson('3108962099').should.equal(true); | ||
kennitala.isPerson('310896-2099').should.equal(true); | ||
kennitala.isPerson(3108962099).should.equal(true); | ||
kennitala.isPerson('31089daa62099').should.equal(true); | ||
}); | ||
describe("kennitala", function () { | ||
describe("#isPerson", function () { | ||
it("should validate known valid personal kennitala-s of various formats", function () { | ||
kennitala.isPerson("3108962099").should.equal(true); | ||
kennitala.isPerson("310896-2099").should.equal(true); | ||
kennitala.isPerson(3108962099).should.equal(false); | ||
kennitala.isPerson("31089daa62099").should.equal(false); | ||
}); | ||
it("should not validate company kennitala-s or plain invalid ones either", function () { | ||
kennitala.isPerson('6010100890').should.equal(false); | ||
kennitala.isPerson(9908962099).should.equal(false); | ||
}); | ||
it("should not validate company kennitala-s or plain invalid ones either", function () { | ||
kennitala.isPerson("6010100890").should.equal(false); | ||
kennitala.isPerson(9908962099).should.equal(false); | ||
}); | ||
it("should not validate kennitala with 13th month", function () { | ||
kennitala.isPerson('1337991337').should.equal(false); | ||
}); | ||
}); | ||
it("should not validate kennitala with 13th month", function () { | ||
kennitala.isPerson("1337991337").should.equal(false); | ||
}); | ||
}); | ||
describe("#isCompany", function () { | ||
it("should validate known valid company ids", function () { | ||
kennitala.isCompany('6010100890').should.equal(true); | ||
kennitala.isCompany('601010-0890').should.equal(true); | ||
kennitala.isCompany(6010100890).should.equal(true); | ||
}) | ||
describe("#isCompany", function () { | ||
it("should validate known valid company ids", function () { | ||
kennitala.isCompany("6010100890").should.equal(true); | ||
kennitala.isCompany("601010-0890").should.equal(true); | ||
kennitala.isCompany(6010100890).should.equal(false); | ||
}); | ||
it("should not validate personal kennitala-s", function () { | ||
kennitala.isCompany('3108962099').should.equal(false); | ||
}); | ||
}); | ||
it("should not validate personal kennitala-s", function () { | ||
kennitala.isCompany("3108962099").should.equal(false); | ||
}); | ||
}); | ||
describe("#isTemporary", function () { | ||
it("should validate temporary ids", function () { | ||
kennitala.isTemporary('8241251291').should.equal(true); | ||
kennitala.isTemporary('902412-2041').should.equal(true); | ||
kennitala.isValid('8241251291').should.equal(true); | ||
kennitala.isValid('902412-2041').should.equal(true); | ||
kennitala.isValid(9591601299).should.equal(true); | ||
kennitala.isTemporary(9591601299).should.equal(true); | ||
}) | ||
describe("#isTemporary", function () { | ||
it("should validate temporary ids", function () { | ||
kennitala.isTemporary("8241251291").should.equal(true); | ||
kennitala.isTemporary("902412-2041").should.equal(true); | ||
kennitala.isValid("8241251291").should.equal(true); | ||
kennitala.isValid("902412-2041").should.equal(true); | ||
kennitala.isValid(9591601299).should.equal(false); | ||
kennitala.isTemporary(9591601299).should.equal(false); | ||
}); | ||
it("should not validate invalid ids", function () { | ||
kennitala.isTemporary('0925120590').should.equal(false); | ||
}); | ||
}); | ||
it("should not validate invalid ids", function () { | ||
kennitala.isTemporary("0925120590").should.equal(false); | ||
}); | ||
}); | ||
describe("#generateKennitala", function () { | ||
it("should generate my id", function () { | ||
kennitala.generatePerson(new Date("1996-08-31"), 20).should.equal("3108962099") | ||
}) | ||
}); | ||
describe("#generateKennitala", function () { | ||
it("should generate my id", function () { | ||
kennitala | ||
.generatePerson(new Date("1996-08-31"), 20) | ||
.should.equal("3108962099"); | ||
}); | ||
}); | ||
describe("#sanitize inputs", function () { | ||
it("should remove invalid characters in kennitölur", function () { // ég bara gat ekki skrifað kennitala-s einu sinni í viðbót >_< | ||
kennitala.sanitize('310896DIRTYSSID2099').should.equal('3108962099'); | ||
describe("#sanitize inputs", function () { | ||
it("should give undefined for invalid formats", function () { | ||
should.equal(kennitala.sanitize("310896DIRTYSSID2099"), undefined); | ||
should.equal(kennitala.sanitize("6010sfa100890"), undefined); | ||
}); | ||
kennitala.sanitize('6010sfa100890').should.equal('6010100890'); | ||
}); | ||
it("should give undefined for non string types", function () { | ||
should.equal(kennitala.sanitize(3108962099), undefined); | ||
}); | ||
}); | ||
it("should convert kennitölur of type int to string", function () { | ||
kennitala.sanitize(3108962099).should.be.a('string').and.equal('3108962099'); | ||
}); | ||
}); | ||
describe("#format input", function () { | ||
it("should ensure string follows format xxxxxx-xxxx", function () { | ||
kennitala.format("31089620").should.equal("310896-20"); | ||
}); | ||
}); | ||
describe("#test people", function () { | ||
it("should validate test people from the test dataset", function () { | ||
should.equal( | ||
kennitala.isPerson("1908991529", { allowTestDataset: false }), | ||
false | ||
); | ||
should.equal( | ||
kennitala.isPerson("1909021450", { allowTestDataset: true }), | ||
true | ||
); | ||
should.equal( | ||
kennitala.isValid("1905641429", { allowTestDataset: true }), | ||
true | ||
); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
458
35134
10
152