Skip to content
This repository has been archived by the owner on Dec 21, 2020. It is now read-only.

Commit

Permalink
fix randomInteger
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Kiel committed Jun 23, 2020
1 parent 524dab9 commit c598e77
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
18 changes: 18 additions & 0 deletions src/randomInteger.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ describe('testing random-number generator', function () {
}
})

it(`should output values between '0' and '8'`, function () {
let result: number
for (let i = 0; i < ATTEMPTS; i++) {
result = randomInteger(0, 8)

assert(0 <= result && result < 8)
}
})

it(`should output values between '23' and '7500000'`, function () {
let result: number
for (let i = 0; i < ATTEMPTS; i++) {
result = randomInteger(23, 7500000)

assert(23 <= result && result < 7500000)
}
})

it('should throw error for falsy interval input', function () {
assert.throws(() => randomInteger(2, 1))

Expand Down
20 changes: 13 additions & 7 deletions src/randomInteger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { randomBytes } from 'crypto'

const MAX_SAFE_INTEGER = 2147483647
/**
* @param start
* @param end
Expand All @@ -23,17 +24,20 @@ export function randomInteger(start: number, end?: number): number {
// Projects interval from [start, end) to [0, end - start)
let interval = end == null ? start : end - start

if (interval >= Math.pow(2, 32)) {
if (interval > MAX_SAFE_INTEGER) {
throw Error(`Not implemented`)
}

const byteAmount = 32 - Math.clz32(interval - 1)
const bitAmount = 32 - Math.clz32(interval - 1)

const byteAmount = Math.ceil(bitAmount / 8)

let bytes = randomBytes(byteAmount)

let bytes = randomBytes(Math.max(byteAmount / 8, 1))
let bitCounter = 0
let byteCounter = 0

function nextBit(): number {
const nextBit = (): number => {
let result = bytes[byteCounter] % 2
bytes[byteCounter] = bytes[byteCounter] >> 1
if (++bitCounter == 8) {
Expand All @@ -45,9 +49,11 @@ export function randomInteger(start: number, end?: number): number {

let result = 0
for (let i = 0; i < byteAmount; i++) {
if ((result | (1 << i)) < interval) {
if (nextBit() == 1) {
result |= 1 << i
for (let j = 0; j < 8; j++) {
if ((result | (1 << (i * 8 + j))) < interval) {
if (nextBit()) {
result |= 1 << (i * 8 + j)
}
}
}
}
Expand Down

0 comments on commit c598e77

Please sign in to comment.