diff --git a/src/CONST.js b/src/CONST.js index 7ef3640fbb4b..80f20c5f4f53 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -790,6 +790,8 @@ const CONST = { INVITE: 'invite', LEAVE_ROOM: 'leaveRoom', }, + MAX_64BIT_LEFT_HALF: 9_223_372_036, + MAX_64BIT_RIGHT_HALF: 854_775_807, IOS_KEYBOARD_SPACE_OFFSET: -30, }; diff --git a/src/libs/NumberUtils.js b/src/libs/NumberUtils.js new file mode 100644 index 000000000000..d9c980b11cc0 --- /dev/null +++ b/src/libs/NumberUtils.js @@ -0,0 +1,32 @@ +import CONST from '../CONST'; + +/** + * Generates a random positive 64 bit numeric string by randomly generating the left half and right half and concatenating them. Used to generate client-side ids. + * @returns {String} string representation of a randomly generated 64 bit signed integer + */ +/* eslint-disable no-unused-vars */ +function rand64() { + // Max 64-bit signed: + // 9,223,372,036,854,775,807 + // The left part of the max 64-bit number *+1* because we're flooring it + const left = Math.floor(Math.random() * (CONST.MAX_64BIT_LEFT_HALF + 1)); + + // The right part of the max 64-bit number *+1* for the same reason + let right; + + // If the top is any number but the highest one, we can actually have any value for the rest + if (left !== CONST.MAX_64BIT_LEFT_HALF) { + right = Math.floor(Math.random() * 1_000_000_000); + } else { + right = Math.floor(Math.random() * (CONST.MAX_64BIT_RIGHT_HALF + 1)); + } + + // Pad the right with zeros + const rightString = right.toString().padStart(9, '0'); + + return left + rightString; +} + +module.exports = { + rand64, +}; diff --git a/tests/unit/NumberUtilsTest.js b/tests/unit/NumberUtilsTest.js new file mode 100644 index 000000000000..76cb991f3756 --- /dev/null +++ b/tests/unit/NumberUtilsTest.js @@ -0,0 +1,13 @@ +const NumberUtils = require('../../src/libs/NumberUtils'); + +describe('libs/NumberUtils', () => { + it('should generate a random 64-bit numeric string', () => { + const id = NumberUtils.rand64(); + expect(typeof id).toBe('string'); + // eslint-disable-next-line no-undef + expect(BigInt(id)).toBeLessThanOrEqual(BigInt(9223372036854775807)); + // eslint-disable-next-line no-undef + expect(BigInt(id)).toBeGreaterThanOrEqual(0); + }); +}); +