Может ли crypto.getRandomValues ​​(новый Uint32Array (1)) [0] / lim когда-либо быть отрицательным? - PullRequest
0 голосов
/ 13 марта 2020

Любопытно, может ли выражение crypto.getRandomValues(new Uint32Array(1))[0] / lim быть когда-либо отрицательным.

Код, который я конвертирую, помещает в него оболочку Math.abs, но некоторые из нас думают, что для него невозможно быть отрицательным, так просто хотел посмотреть, что думают остальные?

var lim = Math.pow(2, 32) - 1;
crypto.getRandomValues(new Uint32Array(1))[0] / lim);

Это связанный вопрос для большего контекста: Преобразование getRandomValue.browser из cuid в Typescript?

В библиотеке есть функция getRandomValue() nodejs, которая выглядит следующим образом:

import * as crypto from "crypto"

var lim = Math.pow(2, 32) - 1;

export function getRandomValue () {
  return Math.abs(crypto.randomBytes(4)
    .readInt32BE(0) / lim)
}

Я думаю, что для браузера вызов Math.abs был сохранен, даже если кажется, что в этом нет необходимости, и довольно возможно неверно.

1 Ответ

1 голос
/ 13 марта 2020

В этом случае использование Math.abs() было бы неверно!

Рассматриваемое выше объявление, как говорится в объявлении, UInt32 ... без знака 32- бит целое число.

Это просто означает, что самый левый бит (самый значимый бит) не , который следует интерпретировать как бит знака. Это, однако, не мешает вам непреднамеренно использовать значение в некотором контексте, который будет предполагать, что MSB=1 означает «отрицательный».

Тем не менее, это будет неправильно для вас использовать abs(), потому что это преобразует весь битовый шаблон, если он обнаружит, что MSB=1, в совершенно другой битовый шаблон. Поскольку MSB - это просто «один из 32 битов, составляющих значение», абсолютно неправильно делать с ним все, что предполагает, что это знаковый бит. И вы также хотите позаботиться о том, чтобы оно никогда не отображалось как отрицательное число, потому что это не так. Это количество длиной 32 бита, а не 31 + знак. Убедитесь, что так всегда выглядит.

...