Forum Discussion
Ensuring a Random Number is not Re-picked
This one might be for the javascript experts in the community, but open to all.
I think someone (and it might have been Owen Holt) posted how you can use javascript to create a random variable and in that same coding ensure any of the x numbers is not re-picked. I may be imagining this though. (If this does exist can someone point us to the discussion thread)
With the Storyline 360 and the random variable option, does someone have a method they have come up with to ensure the same random number does not get picked more than once?
- k1967hHayesCommunity Member
Owen and Scott - here is a challenge for you!
I have variable for student names (newName) and I am using some neat code (not mine) to grab a bunch of scores from my (SCORM 1.2) file to record results in a Google Sheet
Now I want to record the student name in the file too - but I want to encrypt the name so others can't determine whose score is whose.
The encryption doesn't need to to be very strong - a Ceasar Cipher or something of that level would be sufficient.
So I need a simple script that takes a text value (newName = "Kevin Hayes" for instance), encrypts it (so it's stored as newNamecode in the Sheet = "ahjdh hjkkh"); but in such a way that I can then decypher it back to plain text as I know the key so I can know whose score is whose.
- OwenHoltSuper Hero
You could just use 2 arrays, one with the possible characters and one with the target character. Next, convert your name into an array, find matching values in the first array, and replace them with the corresponding value from the 2nd array. Something like the following:
var str = "Hello WOrld!"; //Replace with your StoryLine name variable.
str = str.toUpperCase();
var n = str.length;
var base = ['Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','1','2','3','4','5','6','7','8','9','0','!','*','-',' ',];
var target = ['B','N','M','1','2','3','4','5','6','7','8','9','0','!','*','-','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V',' ',];
str = str.split("");
for (var i = 0; i < n; i++) {
for (var ii = 0; ii<40; ii++) {
if(str[i] == base[ii]){
str[i] = target[ii];
}
}
};str = str.join('');
console.log(str); //Send this back to StoryLine or to your score boardIf you run this in your browser console, it should return 'VPEEH OHAEZX'
If you replace Hello WOrld! with Owen Holt and run it again, you will get HOPO VHES- k1967hHayesCommunity Member
Brilliant
I need to play with this using the JavaScript trigger and see how far
I get it to workSent from my iPhone
- k1967hHayesCommunity Member
What additional code do I need to save the resultant string into a VAR I can then store in Storyline?
- OwenHoltSuper Hero
GetPlayer().SetVar('YourSL Variable', str);
- ScottWiley1Community Memberfound here
Hi Kevin,
If you don't need anything so custom, and could get by with a type of "masking" approach, I Googled a simple JavaScript encryption method (found here) that converts your string into Base64 and back.
For my test In Storyline, I created 3 text variables (baseString, encodedString, and decodedString).
On the stage, I created a text entry field (the default TextEntry 1 variable changed to the baseString variable).
Then added 2 buttons (one to encrypt and one to decrypt) with JavaScript triggers that will convert the entered text and display in two additional text fields displaying the other 2 variables (encodedString, and decodedString).
On the encrypt button, I added this JavaScript to the trigger:
var player = GetPlayer();
//The baseString variable could be populated by retrieving the learner name from the LMS, but just used text entry here.
var baseString = player.GetVar("baseString");//Convert to base64
var encodedString = window.btoa( baseString );//Display in text field, but this could be sent to your Google sheet.
player.SetVar("encodedString", encodedString);On the decrypt button, it goes the other way:
var player = GetPlayer();
//Grab the encoded text
var encodedString = player.GetVar("encodedString");//Convert back to normal text
var decodedString = window.atob( encodedString );//Display in the text field
player.SetVar("decodedString", decodedString);The test file is attached.
Hope that helps.
- k1967hHayesCommunity Member
Wow Owen - you really are a "Hero"
So doing this will record the string HOPO VHES in my Google Sheet instead of Owen Holt.
Is there a simple and sexy way I can then decode the strings back using a formula in Google Sheet or something?
- OwenHoltSuper Hero
Looking at my code and it isn't quite right. I'll need to troubleshoot it a bit longer to make sure it works correctly consistently.
Scott's solution is a good one that I also considered, however my only concern would be that the btoa() method is not supported in IE9 and earlier. If that isn't a concern for your target audience, it is a nice simple and clean solution. - k1967hHayesCommunity Member
Yeah I do like the idea of the Base64 and actually is one I tried myself but couldn't get it to work - so will definitely try Scott's solution. What's neat about using Base64 is that there is (from memory) an exsisting formula within Google Sheets that easily reverts strings "back" from Base64 - so that would be cool. If I wanted another layer of encryption I guess Base64, then a randomiser a'la Owen, and that would be pretty hard to break but fairly easy to reverse/unencrypt.
Scott & Owen - thanks!
- k1967hHayesCommunity Member
Scott and Owen - thanks so much for all your help. In the end I went for Scott's Base64 Solution although really liked Owen's idea (if you get the code working would love to take a look!)
Combining Scott's solution with the Google Sheet data export (see: https://community.articulate.com/discussions/articulate-storyline/articulate-storyline-export-to-google-drive ) means I can now automatically track a very sophisticated assessment using a SCORM 1.2 LMS (for Pass/Fail & Overall Score) and (simultaneously) store additional assessment data in a Google Sheet (see attached image)
The bonus is that there is a script available within Google Sheets that enables me to reverse the Base64 to Ascii (see:https://www.reddit.com/r/googlesheets/comments/4y2ebb/help_decoding_column_of_base64_data/) - so all in all a neat solution that enables me to "hide" user names (albeit not enough to stop an uber tracker but sufficient for my purposes) and I can easily unencrypt the Base64 by just copying the data into a sheet that has been setup with the Base64 reverse script.
Once again - thanks!
- VirgilSimpeloCommunity Member
Owen, thank you for contributing this. It took me a few days to find a solution. I thought splicing the array would help, but it didn't seem to be working and presented a "Nan" variable in my output. I'm sure I did something wrong in my javascript, but you detailed it nicely so that I could understand. Thank you so much!
- OwenHoltSuper Hero
Glad you found it useful!