Reputation: 146
I'm trying to create a set of JavaScript functions which can generate a 6 character code from some defined alphanumeric string (changeable, so it's easier for Latin or Cyrillic, etc. alphabet users, depending) and also validate that code if it's typed instead of generated. I was trying to use a combination of the code from this thread and a text box already present in the application I'm using, but it's simply not working because I don't know enough about JS.
Here is what I've started building myself, and as you will see, I've put in comments to outline my thought on the process from beginning to end. I have no idea how to assign each letter a specific value though.
The idea here is that I need this for uniqueness, not security. Speed is also preferable, but none of this seems so complicated that it cannot run quickly. There is no network connection on the devices (Android tablets) when they are running this code.
// Writing Psudo Code for a JS Function to create (or validate) a checksum ID variable from a list of input characters:
// Setup:
// Take in a list of possible alpha characters:
var charset = 'АБВГДЖЗКЛМНОПРСТУФХЧЭЮЯ';
// Make sure all are letters, no numbers or symbols. Throw error.
// /^[a-zA-Z]+$/ or maybe /[\wа-яА-Я]+/ig
// Now calculate the length (num of characters), n:
function NumberOfValidInputCharacters () {
return charset.length;
}
// Create a string of 5 random characters from the list.
function makeid() {
var text = '';
// Note:change 4 to the desired length of the ID. Since it starts at 0, 4 means an actual length of 5.
for (var i = 0; i <= 4; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
// Assign each character a value from 1 to n: value1 - value5
//**I think in order to do this I'll have to set the return to an array, as JS doesn't allow multiple returns.
// Math Ops:
function makechecksum() {
// Separate out the characters into 5 separate vars: char1 - char5
// Map to values from setup.
// Run some math ops on the 5 values as follows:
// 2*value1
var val1 = 2*value1
// value2*value2
var val2 = value2**2
// (value3 +1)*value4
var val3 = (value3 +1)*value4
// (value5^3) - 1
var val4 = (value5**3) - 1
// Place the results into an array
var ArrayValue = [val1, val2, val3, val4]
// Sum the results
var addend = sum(ArrayValue)
// Divide the result by charset.length, capture the remainder.
var final_digit = (addend % charset.length);
// Assign the remainder to it's corresponding character from previous step, label as char6.
// Create id code by concatenating char1 - char6. Return.
var full_id = text.concat(final_digit);
}
//Validate ID code (Take a code entered and validate it.)
// Duplicate variable, remove char6,
testString = testString.toUpperCase();
var testString = text.substring(0,4)
// Now run the rest of string of new vars characters through value assignment and Math Ops.
// Compare origial variable to newly created one. If unequal throw error.
//Stuff newly generated Checksum ID into the blank
inputs.stu_id.addEventListener('change', function() {
if (inputs.student_id.value == '')
inputs.student_id.value = codePoint()
})
Upvotes: 0
Views: 468
Reputation: 2925
I've tried the first part of the algorithm, but I'm not sure if you intend the result of makeID()
to be a string or an array of numbers. I went with string. The characters are assigned a numerical value by using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode for the inverse. The problem is that your math operations produce large values that don't fit into the 0 - 65535
range of String.fromCharCode()
. As a result you'll see the "question mark" unicode symbol.
const charset = 'АБВГДЖЗКЛМНОПРСТУФХЧЭЮЯ';
const numSampledChars = 5;
const makeID = (str) => {
const charCodes = Array.from(str.substr(0, numSampledChars)).map(char => char.charCodeAt(0));
console.log('charCodes:', charCodes);
charCodes[0] = charCodes[0] * 2;
charCodes[1] = charCodes[1] * charCodes[1];
charCodes[2] = (charCodes[2] + 1) * charCodes[3];
charCodes[3] = (charCodes[4] ** 3) - 1;
console.log('charCodes after math:', charCodes);
const sumCharCodes = charCodes.reduce((result, code) => result + code, 0);
console.log('sumCharCodes:', sumCharCodes);
const charCodeToAppend = sumCharCodes % charset.length;
console.log('charCodeToAppend:', charCodeToAppend);
return charCodes.concat([charCodeToAppend]).map(code => String.fromCharCode(code)).join('');
};
const inputStr = 'МНОПРСТУФМНОПРСТУФМНОПРСТУФ';
console.log('makeID result:', makeID(inputStr));
This prints:
charCodes: [ 1052, 1053, 1054, 1055, 1056 ]
charCodes after math: [ 2104, 1108809, 1113025, 1177583615, 1056 ]
sumCharCodes: 1179808609
charCodeToAppend: 11
makeID result: ࠸﯁翿Р
Upvotes: 1