Использование / dev / random, / dev / urandom для генерации случайных данных


12

Я ищу способы использования /dev/random(или /dev/urandom) из командной строки. В частности, я хотел бы знать, как использовать такой поток, stdinчтобы записывать потоки случайных чисел stdout(по одному числу в строке).

Меня интересуют случайные числа для всех числовых типов, которые изначально поддерживает архитектура машины. Например, для 64-битной архитектуры они будут включать 64-битные целые числа со знаком и без знака и 64-битные числа с плавающей запятой. Что касается диапазонов, то подойдут максимальные диапазоны для различных числовых типов.

Я знаю, как сделать все это с помощью универсальных интерпретаторов, таких как Perl, Python и т. Д., Но я хотел бы знать, как это сделать с помощью «более простых» инструментов из оболочки. (Под «проще» я подразумеваю «более вероятно, что он будет доступен даже при очень минимальной установке Unix».)

По сути, проблема сводит проблему преобразования двоичных данных в их строковые представления в командной строке. (Например, это не будет делать:. printf '%f\n' $(head -c8 /dev/random))

Я ищу не зависящие от раковины ответы. Также разница между /dev/randomи /dev/urandomне важна для этого вопроса. Я ожидаю, что любая процедура, которая работает для одного, будет работать для другого, даже если семантика результатов может отличаться.


Я адаптировал ответ EightBitTony для создания функций tointsи т. Д., Показанных ниже.

Пример использования:

% < /dev/urandom toprobs -n 5
0.237616281778928
0.85578479125532
0.0330049682019756
0.798812391655243
0.138499033902422

Примечания:

  1. Я использую hexdumpвместо, odпотому что это дало мне более простой способ форматировать вывод, как я хотел;
  2. Досадно, hexdumpчто 64-битные целые числа не поддерживаются (wtf ???);
  3. Интерфейс функций нуждается в работе (например, они должны принимать -n5также -n 5), но, учитывая мои жалкие навыки программирования оболочки, это было лучшее, что я мог собрать быстро. (Комментарии / улучшения приветствуются, как всегда.)

Большое удивление, которое я получил от этого упражнения, заключалось в том, как трудно запрограммировать на оболочке самые элементарные числовые вещи (например, прочитать шестнадцатеричное число с плавающей запятой или получить максимальное значение собственного числа с плавающей запятой) ...


_tonums () {
  local FUNCTION_NAME=$1 BYTES=$2 CODE=$3
  shift 3

  local USAGE="Usage: $FUNCTION_NAME [-n <INTEGER>] [FILE...]"
  local -a PREFIX

  case $1 in
    ( -n ) if (( $# > 1 ))
           then
               PREFIX=( head -c $(( $2 * $BYTES )) )
               shift 2
           else
               echo $USAGE >&2
               return 1
           fi ;;
    ( -* ) echo $USAGE >&2
           return 1 ;;
    (  * ) PREFIX=( cat ) ;;
  esac

  local FORMAT=$( printf '"%%%s\\n"' $CODE )
  $PREFIX "$@" | hexdump -ve $FORMAT
}

toints () {
  _tonums toints 4 d "$@"
}

touints () {
  _tonums touints 4 u "$@"
}

tofloats () {
  _tonums tofloats 8 g "$@"
}

toprobs () {
  _tonums toprobs 4 u "$@" | perl -lpe '$_/=4294967295'
}

1
tr -cs '[:digit:]' '[\n*]' </dev/urandomдолжен дать вам только целое число.
cuonglm

Насколько мне известно, / dev / random не генерирует случайные числа как таковые, но добавляет шум к математическим функциям, которые дают псевдослучайное число, чтобы они стали менее предсказуемыми. Возможно, вы захотите взглянуть на randomlib.sourceforge.net
Руи Ф. Рибейро,


Вам нужна случайность с крипто-качеством или, например, достаточно ли качественный посев в зависимости от времени?
Жиль "ТАК ... перестать быть злым"

@ Жиль: мотивация для моего вопроса была больше узнать об инструментах оболочки и Unix, чем о случайности; Я просто хотел узнать, какие базовые инструменты Unix существуют для преобразования потока двоичных данных в их строковое представление.
kjo

Ответы:


21

Вы можете использовать, odчтобы получить номера из /dev/randomи /dev/urandom.

Например,

2-байтовые беззнаковые десятичные числа,

$ od -vAn -N2 -tu2 < /dev/urandom
24352

1-байтовое десятичное целое число со знаком,

$ od -vAn -N1 -td1 < /dev/urandom
-78

4-байтовые беззнаковые десятичные числа,

$ od -vAn -N4 -tu4 < /dev/urandom
3394619386

man odдля получения дополнительной информации о od.


8

Некоторые оболочки (например bash(1)) имеют $RANDOM«переменную», которая дает случайные числа.


1

Вы могли бы сделать что-то вроде:

perl -le '
  while (q(
    c char,  C unsigned char, s! short, S! unsigned short,
    i! int,  I! unsigned int, l! long,  L! unsigned long,
    f float, d double,) =~ /(\S+) (.*?),/gs) {
    $size = length(pack $1, 0);
    sysread STDIN, $data, $size;
    print "$2($size): " . unpack($1, $data);
  }' < /dev/urandom

Что в 64-битной системе даст вам что-то вроде:

char(1): -98
unsigned char(1): 62
short(2): -12526
unsigned short(2): 399
int(4): 499066219
unsigned int(4): 2312134917
long(8): -4889591208978026255
unsigned long(8): 2080566823379835456
float(4): 55.4727554321289
double(8): 8.6395690272822e-05
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.