Skip to content

Instantly share code, notes, and snippets.

@maxgr0
Created June 29, 2021 12:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxgr0/45acc0579bde9521be1137a60480fb29 to your computer and use it in GitHub Desktop.
Save maxgr0/45acc0579bde9521be1137a60480fb29 to your computer and use it in GitHub Desktop.
generate-iso-contract-id-checksum
const P1 = [
[0, 1, 1, 1],
[1, 1, 1, 0],
[1, 0, 0, 1],
[0, 1, 1, 1],
[1, 1, 1, 0],
[1, 0, 0, 1],
[0, 1, 1, 1],
[1, 1, 1, 0],
[1, 0, 0, 1],
[0, 1, 1, 1],
[1, 1, 1, 0],
[1, 0, 0, 1],
[0, 1, 1, 1],
[1, 1, 1, 0],
[1, 0, 0, 1],
];
const P2 = [
[0, 1, 1, 2],
[1, 2, 2, 2],
[2, 2, 2, 0],
[2, 0, 0, 2],
[0, 2, 2, 1],
[2, 1, 1, 1],
[1, 1, 1, 0],
[1, 0, 0, 1],
[0, 1, 1, 2],
[1, 2, 2, 2],
[2, 2, 2, 0],
[2, 0, 0, 2],
[0, 2, 2, 1],
[2, 1, 1, 1],
[1, 1, 1, 0],
];
const listAlphaNumeric = {
'0': [0, 0, 0, 0, 0],
'1': [0, 0, 0, 1, 16],
'2': [0, 0, 0, 2, 32],
'3': [0, 0, 1, 0, 4],
'4': [0, 0, 1, 1, 20],
'5': [0, 0, 1, 2, 36],
'6': [0, 0, 2, 0, 8],
'7': [0, 0, 2, 1, 24],
'8': [0, 0, 2, 2, 40],
'9': [0, 1, 0, 0, 2],
A: [0, 1, 0, 1, 18],
B: [0, 1, 0, 2, 34],
C: [0, 1, 1, 0, 6],
D: [0, 1, 1, 1, 22],
E: [0, 1, 1, 2, 38],
F: [0, 1, 2, 0, 10],
G: [0, 1, 2, 1, 26],
H: [0, 1, 2, 2, 42],
I: [1, 0, 0, 0, 1],
J: [1, 0, 0, 1, 17],
K: [1, 0, 0, 2, 33],
L: [1, 0, 1, 0, 5],
M: [1, 0, 1, 1, 21],
N: [1, 0, 1, 2, 37],
O: [1, 0, 2, 0, 9],
P: [1, 0, 2, 1, 25],
Q: [1, 0, 2, 2, 41],
R: [1, 1, 0, 0, 3],
S: [1, 1, 0, 1, 19],
T: [1, 1, 0, 2, 35],
U: [1, 1, 1, 0, 7],
V: [1, 1, 1, 1, 23],
W: [1, 1, 1, 2, 39],
X: [1, 1, 2, 0, 11],
Y: [1, 1, 2, 1, 27],
Z: [1, 1, 2, 2, 43],
};
/**
* Generates the checksum of an ISO contract id
* @param contractId
*/
export const generateISOContractIdChecksum = (contractId: string): string => {
contractId = contractId.replace(/[-\*]?/g, '').toUpperCase();
// validate contract id
const pattern =
/^([A-Za-z]{2})([A-Za-z0-9]{3})([A-Za-z0-9]{9})([A-Za-z0-9])?(?=$)/g;
if (!pattern.test(contractId)) {
throw new Error(
`Contract ID ${contractId} does not fit in validation pattern`,
);
}
if (contractId.length > 14) {
throw new Error(
`Checksum is already included in contract id ${contractId}`,
);
}
const calc = [];
// Digisto Matrix
let counter = 0;
for (let letter = 0; letter < 14; letter++) {
for (let i = 0; i < 4; i++) {
calc[counter] = listAlphaNumeric[contractId[letter]][i];
counter++;
}
}
// Check Equation
let c1 = 0;
let c2 = 0;
let c3 = 0;
let c4 = 0;
for (let i = 0; i < 14; i += 1) {
c1 += calc[i * 4] * P1[i][0] + calc[i * 4 + 1] * P1[i][2];
c2 += calc[i * 4] * P1[i][1] + calc[i * 4 + 1] * P1[i][3];
c3 += calc[i * 4 + 2] * P2[i][0] + calc[i * 4 + 3] * P2[i][2];
c4 += calc[i * 4 + 2] * P2[i][1] + calc[i * 4 + 3] * P2[i][3];
}
c1 = c1 % 2;
c2 = c2 % 2;
c3 = c3 % 3;
c4 = c4 % 3;
const q1 = c1;
const q2 = c2;
let r1, r2;
if (c4 == 0) r1 = 0;
if (c4 == 1) r1 = 2;
if (c4 == 2) r1 = 1;
if (c3 + r1 == 0) r2 = 0;
if (c3 + r1 == 1) r2 = 2;
if (c3 + r1 == 2) r2 = 1;
if (c3 + r1 == 3) r2 = 0;
if (c3 + r1 == 4) r2 = 2;
const revDigit = q1 + q2 * 2 + r1 * 4 + r2 * 16;
// Get Checksum
let k;
for (k in listAlphaNumeric) {
if (listAlphaNumeric.hasOwnProperty(k)) {
if (revDigit == listAlphaNumeric[k][4]) {
break;
}
}
}
return k;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment