Skip to content

Instantly share code, notes, and snippets.

@gabmontes
Last active October 27, 2022 15:01
Show Gist options
  • Save gabmontes/1d585bfcb41137766f98 to your computer and use it in GitHub Desktop.
Save gabmontes/1d585bfcb41137766f98 to your computer and use it in GitHub Desktop.
Validator for "Clave Bancaria Uniforme", or CBU, as used in the Argentinean banking system
/**
* Validator and brute-force checksum generator for "Clave Bancaria Uniforme"
* fromat used in the Argentinan banking system.
*
* Legal stuff at http://www.infoleg.gob.ar/infolegInternet/anexos/45000-49999/47564/norma.htm
* Code based on https://gist.github.com/delucas/4526176
* Universal loader based on https://gist.github.com/jrburke/1262861
*/
/* global define, window */
(function (define) {
var cbuValidator = {};
// Validation error codes
cbuValidator.errorCode = {
"OK": 0,
"BAD_LENGTH": 1,
"BAD_BANKBRANCH": 2,
"BAD_ACCOUNT": 3
};
// Validate CBU code length
cbuValidator.validateCBULength = function (cbu) {
return cbu.length === 22;
};
// Validate the bank/branch section of a CBU
cbuValidator.validateBankBranch = function (code) {
if (code.length != 8) {
return false;
}
var bank = code.substr(0, 3),
checksum1 = code[3],
branch = code.substr(4, 3),
checksum2 = code[7],
sum = bank[0] * 7 + bank[1] * 1 + bank[2] * 3 +
checksum1 * 9 + branch[0] * 7 + branch[1] * 1 + branch[2] * 3,
diff = 10 - (sum % 10);
return diff == checksum2;
};
// Validate the account section of a CBU
cbuValidator.validateAccount = function (num) {
if (num.length != 14) {
return false;
}
var checksum = num[13],
sum = num[0] * 3 +
num[1] * 9 + num[2] * 7 + num[3] * 1 + num[4] * 3 +
num[5] * 9 + num[6] * 7 + num[7] * 1 + num[8] * 3 +
num[9] * 9 + num[10] * 7 + num[11] * 1 + num[12] * 3,
diff = 10 - (sum % 10);
return diff == checksum;
};
// Validate a CBU code
cbuValidator.validateCBU = function (cbu) {
if (cbuValidator.validateCBULength(cbu)) {
if (cbuValidator.validateBankBranch(cbu.substr(0, 8))) {
if (cbuValidator.validateAccount(cbu.substr(8, 14))) {
return cbuValidator.errorCode.OK;
} else {
return cbuValidator.errorCode.BAD_ACCOUNT;
}
} else {
return cbuValidator.errorCode.BAD_BANKBRANCH;
}
} else {
return cbuValidator.errorCode.BAD_LENGTH;
}
};
// Tiny brute force bank + branch + checksums generator
cbuValidator.getBankBranchCode = function (bank, branch) {
if (bank.length !== 3 || branch.length !== 3) {
return null;
}
for (var ck1 = 0; ck1 < 10; ck1++) {
for (var ck2 = 0; ck2 < 10; ck2++) {
var code = bank + ck1 + branch + ck2;
if (cbuValidator.validateBankBranch(code)) {
return code;
}
}
}
};
// Tiny brute force account + checksum generator
cbuValidator.getAccountCode = function (account) {
if (account.length !== 13) {
return null;
}
for (var ck = 0; ck < 10; ck++) {
var code = account + ck;
if (cbuValidator.validateAccount(code)) {
return code;
}
}
};
// expose module interface
define("cbuValidator", function () {
return cbuValidator;
});
})(typeof define === "function" && define.amd ? define : function (id, factory) {
if (typeof module !== "undefined" && module.exports) {
// Node.js
module.exports = factory();
} else {
// Create a global function
window[id] = factory();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment