establishes fixed randomIDs

pull/64/head
macniel 2025-11-01 10:26:24 +01:00
parent 62c5702992
commit 9a57bcd77a
1 changed files with 28 additions and 12 deletions

View File

@ -2,7 +2,7 @@ import {dest, series, src} from 'gulp';
import process from 'node:process'; import process from 'node:process';
import replace from 'gulp-replace'; import replace from 'gulp-replace';
import jsonModify from 'gulp-json-modify'; import jsonModify from 'gulp-json-modify';
import {getRandomValues} from 'node:crypto'; import {subtle} from 'node:crypto';
import * as dartSass from 'sass'; import * as dartSass from 'sass';
import gulpSass from 'gulp-sass'; import gulpSass from 'gulp-sass';
import {deleteAsync} from 'del'; import {deleteAsync} from 'del';
@ -16,19 +16,34 @@ const sass = gulpSass(dartSass);
/** /**
* Generate a random alphanumeric string ID of a given requested length using `crypto.getRandomValues()`. * Generate a random alphanumeric string ID of a given requested length using `crypto.getRandomValues()`.
* @param {string} reference The reference which should be used to generate a semi random ID
* @param {number} length The length of the random string to generate, which must be at most 16384. * @param {number} length The length of the random string to generate, which must be at most 16384.
* @returns {string} A string containing random letters (A-Z, a-z) and numbers (0-9). * @returns {string} A string containing random letters (A-Z, a-z) and numbers (0-9).
*/ */
function randomID(length = 16) { function randomID(reference = "", length = 16) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const encoder = new TextEncoder();
const cutoff = 0x100000000 - (0x100000000 % chars.length); const data = encoder.encode(reference);
const random = new Uint32Array(length); return subtle.digest('SHA-256', data).then(hashBuffer => {
do { // Step 2: Convert the hash to a Base62 string
getRandomValues(random); const base62Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
} while (random.some(x => x >= cutoff)); const hashArray = new Uint8Array(hashBuffer);
let id = ""; let num = BigInt(0);
for (let i = 0; i < length; i++) id += chars[random[i] % chars.length];
return id; // Convert hash buffer to a BigInt
for (let byte of hashArray) {
num = (num << BigInt(8)) | BigInt(byte);
}
let base62Id = '';
while (num > 0) {
const remainder = num % BigInt(62);
base62Id = base62Chars[Number(remainder)] + base62Id;
num = num / BigInt(62);
}
// Step 3: Return the first 16 characters
return base62Id.slice(-length);
});
} }
const convert = function (from, to, ofType, overwrite = true) { const convert = function (from, to, ofType, overwrite = true) {
@ -53,7 +68,8 @@ const convert = function (from, to, ofType, overwrite = true) {
} else { } else {
console.debug("processing file", join(source, file)) console.debug("processing file", join(source, file))
let originalSource = JSON.parse(readFileSync(join(source, file), {encoding: "utf8"})); let originalSource = JSON.parse(readFileSync(join(source, file), {encoding: "utf8"}));
let id = randomID(); let id = randomID("DSA_4-1" + TYPE + originalSource.name.trim());
let targetSource = { let targetSource = {
_id: id, _id: id,