Last active
August 24, 2023 16:08
-
-
Save annibal/5d896cb9a8b708349303baf6de2b9886 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Create a function that transforms an index into an pseudo-random value, where the values are tied to a string | |
* @param salt string, must have at least one [a-z0-9] character | |
* @param parseVal [optional] function(val: number, i: number, saltRange: [number, number]) to transform the salt result | |
* @returns function(idx: number, skipParse: boolean = false), will always return the same value for the specific SALT and IDX | |
*/ | |
const getSaltedRandomFn = (salt, parseVal) => { | |
const safeSalt = (salt || "").replace(/[^a-z0-9]/gi, "").toLowerCase(); | |
const l = safeSalt.length; | |
if (safeSalt.length === 0) { | |
throw new SyntaxError(`Salt "${salt}" yielded an empty salt string`); | |
} | |
let resalt = 1; | |
const bitsLen = Math.min(l, 8) + 2; | |
function getSaltBits(i) { | |
const l = safeSalt.length; | |
const bits = Array(bitsLen) | |
.fill(null) | |
.map((_, p) => (Math.floor(((i + resalt) * 303313) / l ** p) * 1) % l); | |
return bits; | |
} | |
const saltChars = Array.from(new Set(safeSalt.split(""))).sort(); | |
const maxChar = saltChars.slice(-1)[0]; | |
const minChar = saltChars[0]; | |
const maxStr = Array(bitsLen).fill(maxChar).join(""); | |
const minStr = Array(bitsLen).fill(minChar).join(""); | |
const saltRange = [parseInt(minStr, 36), parseInt(maxStr, 36)]; | |
function getSaltedRandom(i, skipParse = false) { | |
const bits = getSaltBits(i); | |
const part = bits.map((x) => safeSalt[x]).join(""); | |
let val = parseInt(part, 36); | |
if (!skipParse && typeof parseVal === 'function') { | |
val = parseVal(val, i, saltRange); | |
} | |
return val; | |
} | |
return getSaltedRandom; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ============= | |
// Example Usage | |
// ============= | |
function main() { | |
// :: helper | |
const scale = (from, to) => { | |
const _scale = (value) => { | |
return ((value - from[0]) * (to[1] - to[0])) / (from[1] - from[0]) + to[0]; | |
}; | |
return _scale; | |
}; | |
const parseSaltValue = (saltVal, i, saltRange) => { | |
const saltScale = scale(saltRange, [0, 100]) | |
const val = saltScale(saltVal); | |
return Number(val.toFixed(2)); | |
} | |
// :: example parameters to use as salt | |
const someObj = { id: 'clksm617605rfpt270sx34eri' }; | |
const selectedDate = new Date(); | |
const someParameter = 'development'; | |
// Since these strings are concatenated into a salt string, | |
// the getSaltVal(i) will always return the same value | |
// for the specific i, but for each different i it will | |
// generate seemingly random numbers. Then parseSaltValue() | |
// scales the generated number into a [0, 100] range and | |
// limits the result to 2 decimals. | |
const strSalt = [ | |
selectedDate.toJSON(), | |
someObj.id, | |
someParameter, | |
].join(''); | |
// :: usage | |
const getSaltVal = getSaltedRandomFn(strSalt, parseSaltValue); | |
const from = +new Date(selectedDate.toJSON().split('T')[0] + 'T12:00:00Z'); | |
const to = +new Date(selectedDate.toJSON().split('T')[0] + 'T15:00:00Z'); | |
const bin = 20 * 60 * 1000; | |
let i = 0; | |
const r = []; | |
for (let binDt = from; binDt < to; binDt += bin) { | |
r.push({ | |
time: new Date(binDt), | |
label: new Date(binDt).toJSON().slice(11,16), | |
value: getSaltVal(i++) | |
}); | |
} | |
return r; | |
} | |
console.log(main()) | |
// result = [ | |
// { label: "12:00", value: 50.11, time: Date }, | |
// { label: "12:20", value: 42.07, time: Date }, | |
// { label: "12:40", value: 34.34, time: Date }, | |
// { label: "13:00", value: 11.13, time: Date }, | |
// { label: "13:20", value: 72.15, time: Date }, | |
// { label: "13:40", value: 93.95, time: Date }, | |
// { label: "14:00", value: 21.1, time: Date }, | |
// { label: "14:20", value: 5.07, time: Date }, | |
// { label: "14:40", value: 7.31, time: Date } | |
// ] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment