UNPKG

shuffrand

Version:

Cryptographically secure randomness and shuffling — with soul.

109 lines (108 loc) 3.64 kB
import { cryptoStringParamsSchema as f } from "./types.es.js"; import { cryptoRandom as y } from "./random.es.js"; import { cryptoShuffle as m } from "./shuffle.es.js"; import { Constants as i } from "./constants.es.js"; /** * shuffrand - Cryptographically Secure Random String Generation * * This file contains the core logic for generating cryptographically secure random strings, * adhering to a flat, dot-categorized structure for clarity. * * @author Doron Brayer <doronbrayer@outlook.com> * @license MIT */ const p = { alphanumeric: i.ALPHANUMERIC_CHARS, numeric: i.DIGITS, alpha: i.LATIN_LETTERS, hex: i.HEX_CHARS, uppercase: i.LATIN_UPPERCASE_LETTERS, lowercase: i.LATIN_LOWERCASE_LETTERS }; function C(t = {}) { if (t === null) throw new TypeError( "Invalid cryptoString parameters: 'rawParams' cannot be null. Please provide an object or omit it." ); try { f.assert(t); } catch (e) { throw new TypeError(`Invalid cryptoString parameters: ${e.summary || e.message}`); } const r = t.length ?? 16, n = t.characterSet ?? "alphanumeric", h = t.noRepeat ?? !1; if (r > 1e6) throw new TypeError( "Invalid cryptoString parameters: 'length' exceeds maximum safe limit of 1,000,000 characters." ); let a; if (typeof n == "string" && Object.prototype.hasOwnProperty.call(p, n)) a = p[n]; else { a = n; const e = Array.from(a); if (new Set(e).size !== e.length) throw new TypeError( "Invalid cryptoString parameters: Custom character set contains duplicate characters, which would skew randomness distribution." ); } if (a.length === 0 && r > 0) throw new TypeError("Invalid cryptoString parameters: The resolved 'characterSet' cannot be empty."); const s = Array.from(new Set(Array.from(a))); if (s.length < 2 && r > 1) throw new TypeError( "Invalid cryptoString parameters: Character set must contain at least 2 unique characters to generate a string longer than 1." ); if (h && r > s.length) throw new TypeError( `Invalid cryptoString parameters: Cannot generate a string of length ${r} with no repeats from a character set with only ${s.length} unique characters.` ); if (r === 0) return ""; if (h) return m(s).slice(0, r).join(""); { const e = new Array(r), o = Array.from(a), l = o.length; for (let c = 0; c < r; c++) { const u = y({ lowerBound: 0, upperBound: l - 1, typeOfNum: "integer", exclusion: "none" }); e[c] = o[u]; } return e.join(""); } } function d(t = {}) { try { f.assert(t); } catch (o) { throw new TypeError(`Invalid calculateStringEntropy parameters: ${o.summary || o.message}`); } const r = t.length ?? 16, n = t.characterSet ?? "alphanumeric", h = t.noRepeat ?? !1; let a; typeof n == "string" && Object.prototype.hasOwnProperty.call(p, n) ? a = p[n] : a = n; const e = new Set(Array.from(a)).size; if (h) { if (r > e) throw new TypeError( `Invalid calculateStringEntropy parameters: Cannot calculate entropy for a length of ${r} with no repeats from a character set with only ${e} unique characters.` ); let o = 0; for (let l = 0; l < r; l++) { const c = e - l; c > 0 && (o += Math.log2(c)); } return o; } if (e < 2 && r > 1) throw new TypeError( "Invalid calculateStringEntropy parameters: Character set must contain at least 2 unique characters to calculate meaningful entropy." ); return e === 0 ? 0 : Math.log2(e) * r; } export { d as calculateStringEntropy, C as cryptoString };