I'm using Deployd to build an API to be consumed by an AngularJS app. I'm attempting to integrate the ng-s3upload module to save some images on Amazon S3. The ng-s3upload module requires the backend server, in this case deployd, to generate a Base64 encoded policy. I created a GET event to generate the policy but haven't figured out how I can Base64 encode it form within the Deployd event script. Any help or ideas is appreciated. I tried to use the NodeJS Buffer function, Deployd is based on Node, but it is not available form the event script environment.
You can use the btoa() function to encode strings to base64 format.
var encodedStr = btoa(originalString);
EDITED As you say you can't use btoa, I wrote an implementation of a base64 encoding function. You use it just like this:
var base64str = str.toBase64();
Here is the code, you can see it in action in this jsfiddle.
var code = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'];
String.prototype.padLeft = function(desiredLength, padChar) {
if (this.length >= desiredLength) return this;
var count = desiredLength - this.length;
var result = '';
while(count--)
result += padChar;
return result + this;
};
function getBinaryString(str) {
var binaryStr = '';
for (var i = 0; i < str.length; i++) {
binaryStr += str.charCodeAt(i).toString(2).padLeft(8, '0');
}
return binaryStr;
}
function getBase64FromBinaryString(binaryStr) {
var padRightCount = binaryStr.length % 3;
var numChars = binaryStr.length / 6;
var maxChars = numChars - padRightCount;
while (padRightCount--) binaryStr += '00000000';
var result = '';
for (var i = 0; i < numChars; i++) {
var pos = i * 6;
result += code[parseInt(binaryStr.substr(pos, 6), 2)];
}
for (var i = 0; i < (numChars - maxChars); i++)
result += '=';
return result;
}
String.prototype.toBase64 = function() {
var binaryStr = getBinaryString(this);
return getBase64FromBinaryString(binaryStr);
}
Try toString('base64');
var encodedPolicy = new Buffer(policy).toString('base64');
To use node libraries withing deployd event script, you should add plugins: dpd-event and dpd-event-extension.
Go to your app directory.
$ npm install btoa
and then in an event resource import it:
var btoa = require('btoa');
Related
I am new to javaScript and having a terrible time with understanding loops.
Currently I have a random text generator function. I have gotten it to generate random characters from a string but only one character each time the function is ran. I would like to build a string of 20 random characters from the output of the function.
This is what I have so far:
function passGen() {
let text = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWYXZ()!##$%&*/?+-%".split("");
let randomIndex = Math.floor(Math.random() * text.length);
return text[randomIndex];
}
let randomPass = passGen();
I would like to let the function produce the random character and then use a for loop to out put 20 of these random characters in a string.
I can't get
for (let i = 0; i <= 20; i++){
console.log(randomPass)
to work.
Any help is appreciated.
You need to define a string variable and then use a loop to append characters to it, like this:
function passGen () {
const text = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVVWYXZ()!##$%&*/?+-%'.split('')
let res = ''
for (let i = 0; i < 20; i++) {
res += text[Math.floor(Math.random() * text.length)]
}
return res
}
const randomPass = passGen();
You need to specify for yourself what characters you want to support, for example:
function getRandomCharacter(supportedCharacters) {
return supportedCharacters[parseInt(Math.random() * supportedCharacters.length)];
}
function getRandomString(supportedCharacters, length) {
let output = "";
while (length--) output += getRandomCharacter(supportedCharacters);
return output;
}
console.log(getRandomString([
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
], 20));
getRandomCharacter randomizes a character
Math.random() generates a real number which is greater or equal than 0 but smaller than 1
multiplying Math.random() with the number of supported characters scales the value to the interval between [0, length)
parseInt rounds the result down
the result of parseInt can be used as an index
getRandomString generates all the characters using a while loop
length-- evaluates length and then decreases it by 1
+= concatenates the resulting character to output
return output; clarifies that the result of the function is the string
the test sample defines an array (you could do it with a string as well if you want) of the characters you want to support and the length of the string you desire
I'm developing a website for fun that adds a random character to a div element on every key press. I have that part working, but what I need is for the program to check if an English word has been created out of the random characters and highlight that word. I've tried many things, and none have worked. Preferably this would highlight it regardless of whether or not there are spaces surrounding the word, but I will be very happy with really any working code.
This is my current JS for random character generation and autoscrolling, also with some code that doesn't work that is meant to search the code.
var letter = 1
var number = 1
const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u0020']
function typingfunction() {
number = Math.floor(Math.random() * 27)
letter = alphabet[number]
document.getElementById("typing").innerHTML = `${document.getElementById("typing").innerHTML}${letter}`
window.scrollTo(0, document.body.scrollHeight * document.body.scrollHeight);
var input = document.getElementById("typing").innerHTML;
var fs = require('fs');
fs.readFile("words_alpha.txt", function(words) {
var words = words.toString().split('\n').filter(function(word) {
return word.length >= 4;
})});
var output = [];
words.forEach(word); {
if (input.match(word)) {
output.push(word);
}
};
console.log(output);
}
window.addEventListener('keydown', typingfunction)
The code for testing a word basically is OK but there was a syntax error in your code (incorrect format for an anonymous function) and also the words array was only declared inside a function but you tried to use it outside the function.
This code slightly reorganises things to take account of this.
I have no way of testing the nodejs filereading (assuming it is nodejs) so if that causes a problem add the tag to your question to get more help in that area.
The code listens for a click on the window and sets the input HTML empty so several trials can be run.
var letter = 1
var number = 1
const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u0020']
function typingfunction() {
number = Math.floor(Math.random() * 27)
letter = alphabet[number]
document.getElementById("typing").innerHTML = `${document.getElementById("typing").innerHTML}${letter}`
window.scrollTo(0, document.body.scrollHeight * document.body.scrollHeight);
var input = document.getElementById("typing").innerHTML;
var output = [];
words.forEach(word => {
if (input.match(word)) {
output.push(word);
}
});
console.log(output);
}
// first set up the array of words from the file containing them
let words; //declare words here so it can be used later on
let fs = require('fs');
fs.readFile("words_alpha.txt", function(allWords) {
words = allWords.toString().split('\n').filter(function(word) {
return word.length >= 4;
})});
window.addEventListener('keydown', typingfunction);
window.addEventListener('click', function () {document.getElementById("typing").innerHTML = '';});
I'd like to write a function that generates the corresponding column name for a specific number, for example A for 1 or AA for 127. I know this has been answered quite a lot already, but I'd like to do it in a functional way.
Sure, you should be able to convert the existing (imperative) answers pretty easily, but I find myself getting stuck every time I try to.
Any good ideas / functional implementations?
Here's a working implementation.
var letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
function toLetter(number) {
if (!number || number <= 0) {
return 0;
}
var code = "";
for (var i = 0; i < Math.floor(number / 26); i++) {
code += letters[i];
}
code += letters[(number % 26) - 1];
return code;
}
console.log(toLetter(27)); // returns AA;
Good evening everyone,
I am trying to generate a string of 8 characters, which are randomly chosen from an array. This is what I am using:
var myArrayPismo = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
while(myArrayPismo.length < 9){
var randomletter = Math.ceil(Math.random()*myArrayPismo.length)
if(myArrayPismo.indexOf(randomletter) > -1) continue;
myArrayPismo[myArrayPismo.length] = randomletter;
}
Which just prints out all of the letters, for some reason.
And this is my number generating function:
var kodCisla = [];
while(kodCisla.length < 9){
var randomnumber = Math.ceil(Math.random()*9)
if(kodCisla.indexOf(randomnumber) > -1) continue;
kodCisla[kodCisla.length] = randomnumber;
}
Which is working fine. Except I want it to be able to generate 2 or more same numbers, not just different each time.
My goal is to get a random string of letters like this: KODlkSmQW
and a random string of numbers that can also repeat like this: 887562327
Any help on either of these problems would be appreciated.
A function that can pluck a random element from an array would be useful here. Notice the use of Math.floor rather than Math.ceil, and the array access that comes before the return statement.
function randomElement (array) {
return array[Math.floor(Math.random() * array.length)]
}
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
result = '';
for (var i = 0; i < 8; i++) {
result += randomElement(characters)
}
console.log(result) //=> (random 8-character string)
For random numbers, you can use a similar randomInRange function:
function randomInRange (a, b) {
a |= 0
b |= 0
return Math.floor(Math.random() * (b - a + 1)) + a
}
var result = []
for (var i = 0; i < 8; i++) {
result.push(randomInRange(0, 9))
}
console.log(result) //=> (eight random digits)
Your first while loop is never running because it is based on the condition that myArrayPismo.length < 9, which is already false because you just set it to contain all 26 letters. So, when you go to look at it later, you get all the original values. What you need is an additional array to put the generated randoms into.
Also, stay away from a while loop in this case because you know exactly how many times you want to loop, so use a regular for loop instead.
Your second array (with numbers) does this and can certainly come up with the same random twice in a row.
But, both arrays don't need to do any if/then checking before pushing the random into the array.
Finally, as I mentioned, don't use Math.ceil because you'll never get the first element back as a random, use Math.floor instead.
var myArrayPismo = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
var resultArray = [];
for(var i = 0; i < 8; ++i){
resultArray.push(myArrayPismo[Math.floor(Math.random()*myArrayPismo.length)]);
}
console.log(resultArray.join(""));
My question:
Is there any solution that will allow me to process this many characters into a string with Node.js?
The problem:
I need to compute a huge (array, and then) string of character combinations in Node.js, like so:
var fs = require('fs');
var legalChars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '_'];
var fiveChars = [legalChars,
legalChars,
legalChars,
legalChars,
legalChars];
//output all possible combinations of the arrays within
//fiveChars
function allPossibleCases(arr) {
if (arr.length === 0) {
return [];
} else if (arr.length === 1) {
return arr[0];
} else {
var result = [];
var allCasesOfRest = allPossibleCases(arr.slice(1));
// recur with the rest of array
for (var c in allCasesOfRest) {
for (var i = 0; i < arr[0].length; i++) {
result.push(arr[0][i] + allCasesOfRest[c]);
var val = arr[0][i] + allCasesOfRest[c];
}
}
return result;
}
}
// join array of results into string
var result = allPossibleCases(fiveChars).join('", "');
// this essentially writes the string in the form of a Node module
//containing a giant array
fs.writeFile("./data/fiveChars.js",
'fiveChar = ["' + result + '"]; \r\n module.exports = fiveChar;',
function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
I want to continue adding character rows up to 16 rows:
var sixteenChars = [legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars, legalChars];
The problem is that Node cant cope with this all at once.
FATAL ERROR: JS Allocation failed - process out of memory Aborted
I don't want to download more RAM, just looking for a way to handle this calculation process over time rather than filling the memory allocation up.
Since I like using highland these days, I thought I'd post a solution here as an exercise, that I think should scale memory-wise to a lot of combinations. It might be too slow for you I don't know because what you want to generate is 37^16 combinations which is a lot.
This solution will create a file containing all solutions separated by a new line for the 5 chars case. Maybe you can try it and see if it fits your box ;-). Going to the 16 chars case will just need adding new flatMap calls.
Keep me posted ! you can tail -f the file to see it growing.
var fs = require('fs');
var _ = require('highland');
var legalChars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '_'];
var suffixer = function(alphabet) {
var len = alphabet.length;
return function(prefix) {
var i = 0;
return _(function(push, next) {
if (i == len) {
push(null, _.nil);
} else {
push(null, prefix + alphabet[i]);
i++;
}
next();
})
}
}
var s = _(['\n'])
.flatMap(suffixer(legalChars))
.flatMap(suffixer(legalChars))
.flatMap(suffixer(legalChars))
.flatMap(suffixer(legalChars))
.flatMap(suffixer(legalChars))
s.pipe(fs.createWriteStream('alpha.txt'));
Now why you would want to generate so many combinations is another question !