Skip to content

Instantly share code, notes, and snippets.

@wteuber
Last active January 15, 2016 13:00
Show Gist options
  • Select an option

  • Save wteuber/2c481f5f81d2efd39d97 to your computer and use it in GitHub Desktop.

Select an option

Save wteuber/2c481f5f81d2efd39d97 to your computer and use it in GitHub Desktop.
IBAN Validator
/*
https://gist.github.com/wteuber/2c481f5f81d2efd39d97
https://jsfiddle.net/f6f2jves/2/
<body>
<input id="iban" type="text" size="30" autofocus><br>
<span id="check">invalid IBAN</span>
</body>
*/
document.getElementById('iban').onkeyup = function () {
if(validIban(this.value)) {
document.getElementById('check').innerHTML = 'YAY! valid IBAN';
} else {
document.getElementById('check').innerHTML = 'invalid IBAN';
}
this.value = prettyPrint(this.value.replace(/\s/g, '').toUpperCase());
};
var allowedCountries = ['DE'];
var ibanFormats = {
AD: 'ADkk bbbb ssss cccc cccc cccc',
AE: 'AEkk bbbc cccc cccc cccc ccc',
AL: 'ALkk bbbs sssx cccc cccc cccc cccc',
AT: 'ATkk bbbb bccc cccc cccc',
AZ: 'AZkk bbbb cccc cccc cccc cccc cccc',
BA: 'BAkk bbbs sscc cccc ccxx',
BE: 'BEkk bbbc cccc ccxx',
BG: 'BGkk bbbb ssss ddcc cccc cc',
BH: 'BHkk bbbb cccc cccc cccc cc',
BR: 'BRkk bbbb bbbb ssss sccc cccc cccc c',
CH: 'CHkk bbbb bccc cccc cccc c',
CR: 'CRkk bbbc cccc cccc cccc c',
CY: 'CYkk bbbs ssss cccc cccc cccc cccc',
CZ: 'CZkk bbbb ssss sscc cccc cccc',
DE: 'DEkk bbbb bbbb cccc cccc cc',
DK: 'DKkk bbbb cccc cccc cc',
DO: 'DOkk bbbb cccc cccc cccc cccc cccc',
EE: 'EEkk bbss cccc cccc cccx',
ES: 'ESkk bbbb gggg xxcc cccc cccc',
FI: 'FIkk bbbb bbcc cccc cx',
FO: 'FOkk bbbb cccc cccc cx',
FR: 'FRkk bbbb bggg ggcc cccc cccc cxx',
GB: 'GBkk bbbb ssss sscc cccc cc',
GE: 'GEkk bbcc cccc cccc cccc cc',
GI: 'GIkk bbbb cccc cccc cccc ccc',
GL: 'GLkk bbbb cccc cccc cc',
GR: 'GRkk bbbs sssc cccc cccc cccc ccc',
GT: 'GTkk bbbb cccc cccc cccc cccc cccc',
HR: 'HRkk bbbb bbbc cccc cccc c',
HU: 'HUkk bbbs sssx cccc cccc cccc cccx',
IE: 'IEkk aaaa bbbb bbcc cccc cc',
IL: 'ILkk bbbn nncc cccc cccc ccc',
IS: 'ISkk bbbb sscc cccc iiii iiii ii',
IT: 'ITkk xaaa aabb bbbc cccc cccc ccc',
KW: 'KWkk bbbb cccc cccc cccc cccc cccc cc',
KZ: 'KZkk bbbc cccc cccc cccc',
LB: 'LBkk bbbb cccc cccc cccc cccc cccc',
LI: 'LIkk bbbb bccc cccc cccc c',
LT: 'LTkk bbbb bccc cccc cccc',
LU: 'LUkk bbbc cccc cccc cccc',
LV: 'LVkk bbbb cccc cccc cccc c',
MC: 'MCkk bbbb bsss sscc cccc cccc cxx',
MD: 'MDkk bbcc cccc cccc cccc cccc',
ME: 'MEkk bbbc cccc cccc cccc xx',
MK: 'MKkk bbbc cccc cccc cxx',
MR: 'MRkk bbbb bsss sscc cccc cccc cxx',
MT: 'MTkk bbbb ssss sccc cccc cccc cccc ccc',
MU: 'MUkk bbbb bbss cccc cccc cccc cccc cc',
NL: 'NLkk bbbb cccc cccc cc',
NO: 'NOkk bbbb cccc ccx',
PK: 'PKkk bbbb cccc cccc cccc cccc',
PL: 'PLkk bbbs sssx cccc cccc cccc cccc',
PS: 'PSkk bbbb xxxx xxxx xccc cccc cccc c',
PT: 'PTkk bbbb ssss cccc cccc cccx x',
RO: 'ROkk bbbb cccc cccc cccc cccc',
RS: 'RSkk bbbc cccc cccc cccc xx',
SA: 'SAkk bbcc cccc cccc cccc cccc',
SE: 'SEkk bbbc cccc cccc cccc cccc',
SI: 'SIkk bbss sccc cccc cxx',
SK: 'SKkk bbbb ssss sscc cccc cccc',
SM: 'SMkk xaaa aabb bbbc cccc cccc ccc',
TN: 'TNkk bbss sccc cccc cccc cccc',
TR: 'TRkk bbbb bxcc cccc cccc cccc cc',
VG: 'VGkk bbbb cccc cccc cccc cccc'
};
function validIban(iban) {
var isValid = false,
iban = iban.replace(/\s/g, '').toUpperCase(),
country = iban.substr(0, 2);
if (ibanFormats.hasOwnProperty(country)) {
var format = ibanFormats[country].replace(/\s/g, ''),
length = format.length,
checkDigits = iban.charFormatMatch(format, 'k').replace(/\s/g, '');
debugger
isValid = isAllowedCountry(country, allowedCountries) &&
isValidLength(iban, length) &&
isValidFormat(iban) &&
isValidChecksum(iban, checkDigits);
}
return isValid;
}
function checkDigits(iban) {
var idx, ord, chars;
iban = iban.replace(/\s/g, '');
iban = iban.substr(0, 2) + '00' + iban.substr(4);
iban = iban.substr(4) + iban.substr(0, 4);
chars = iban.split('') || [];
for (idx = 0; idx < chars.length; idx += 1) {
ord = chars[idx].charCodeAt(0);
if (ord >= 65 && ord <= 90) {
chars[idx] = (ord - 55).toString();
}
}
iban = chars.join('');
iban = modulo(iban, 97);
iban = (98 - iban);
iban = (iban < 10) ? ("0" + iban.toString()) : iban.toString();
return iban;
}
function prettyPrint(iban) {
iban = iban.replace(/\s/g, '').toUpperCase();
iban = iban.match(/[0-9A-Z]{1,4}/g) || [];
return iban.join(' ');
}
function modulo(divident, divisor) {
var part, partLength = 10;
while (divident.length > partLength) {
part = divident.substring(0, partLength);
divident = (part % divisor) + divident.substring(partLength);
}
return divident % divisor;
}
var isValidLength = function (iban, length) {
return !isTooShort(iban, length) && !isTooLong(iban, length)
}
function isTooShort(iban, min_length) {
var isValid = iban.length >= min_length;
return !isValid;
}
function isTooLong(iban, max_length) {
var isValid = iban.length <= max_length;
return !isValid;
}
function isValidFormat(iban) {
var isValid = /^[A-Z]{2}[0-9]{2}[0-9A-Z]+$/.test(iban);
return isValid;
}
function isAllowedCountry(country, allowed_countries) {
var isValid = allowed_countries.contains('ALL') || allowed_countries.contains(country);
return isValid;
}
function isValidChecksum(iban, digits) {
var isValid = (checkDigits(iban) == digits);
return isValid;
}
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
};
String.prototype.charFormatMatch = function (format, match) {
'use strict';
var frmt = format.substr(0, this.length),
result = '',
chars = frmt.split(''),
idx = 0;
if (typeof match === 'string') {
for (idx = 0; idx < chars.length; idx += 1) {
result += (frmt[idx] === match) ? this[idx] : ' ';
}
}
return result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment