Verwenden Sie / dev / random, / dev / urandom, um zufällige Daten zu generieren

11

Ich suche nach Möglichkeiten, /dev/random(oder /dev/urandom) über die Befehlszeile zu verwenden. Insbesondere möchte ich wissen, wie man einen solchen Stream verwendet stdin, um Zufallszahlenströme zu schreiben stdout(eine Zahl pro Zeile).

Ich interessiere mich für Zufallszahlen für alle numerischen Typen, die die Maschinenarchitektur nativ unterstützt. Bei einer 64-Bit-Architektur umfassen diese beispielsweise 64-Bit-Ganzzahlen mit und ohne Vorzeichen sowie 64-Bit-Gleitkommazahlen. In Bezug auf die Bereiche reichen die maximalen Bereiche für die verschiedenen numerischen Typen aus.

Ich weiß, wie man das alles mit Allzweck-Interpreten wie Perl, Python usw. macht, aber ich würde gerne wissen, wie man das mit "einfacheren" Werkzeugen aus der Shell macht. (Mit "einfacher" meine ich "eher verfügbar, selbst in einer sehr minimalen Unix-Installation".)

Grundsätzlich reduziert das Problem das Konvertieren von Binärdaten in ihre Zeichenfolgendarstellungen in der Befehlszeile. (ZB geht das nicht : printf '%f\n' $(head -c8 /dev/random).)

Ich suche nach muschelunabhängigen Antworten. Auch der Unterschied zwischen /dev/randomund /dev/urandomist für diese Frage nicht wichtig. Ich gehe davon aus, dass jedes Verfahren, das für das eine funktioniert, für das andere funktioniert, auch wenn die Semantik der Ergebnisse unterschiedlich sein kann.


Ich habe die Antwort von EightBitTony angepasst, um die tointsunten gezeigten Funktionen usw. zu erzeugen .

Anwendungsbeispiel:

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

Bemerkungen:

  1. Ich verwende hexdumpstatt, odweil es mir eine einfachere Möglichkeit gab, die Ausgabe so zu formatieren, wie ich es wollte.
  2. Ärgerlicherweise werden hexdump64-Bit-Ganzzahlen (wtf ???) nicht unterstützt.
  3. Die Funktionen Schnittstelle muss arbeiten (zB sollte akzeptieren , -n5als auch -n 5), aber meine klägliche Shell - Programmierung skillz gegeben, das war das Beste , was ich schnell zusammen setzen könnte. (Kommentare / Verbesserungen sind wie immer willkommen.)

Die große Überraschung, die ich durch diese Übung bekam, war herauszufinden, wie schwierig es ist, die elementarsten numerischen Dinge auf der Shell zu programmieren (z. B. einen hexadezimalen Gleitkommawert lesen oder den maximalen nativen Gleitkommawert erhalten) ...


_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'
}
kjo
quelle
1
tr -cs '[:digit:]' '[\n*]' </dev/urandomsollte Ihnen nur eine Ganzzahl geben.
Cuonglm
Soweit mir bekannt ist, erzeugen / dev / random keine Zufallszahlen an sich, sondern fügen den mathematischen Funktionen, die Pseudozufallszahlen geben, Rauschen hinzu, damit sie weniger vorhersehbar werden. Vielleicht möchten Sie sich randomlib.sourceforge.net
Rui F Ribeiro
Benötigen Sie Zufälligkeit in Kryptoqualität oder ist zB das Seeding basierend auf der Zeit gut genug?
Gilles 'SO - hör auf böse zu sein'
@ Gilles: Die Motivation für meine Frage war mehr, sich über Shell- und Unix-Tools als über Zufälligkeit zu informieren. Ich wollte nur wissen, welche grundlegenden Unix-Tools es gibt, um einen Strom von Binärdaten in ihre Zeichenfolgendarstellung zu konvertieren.
Kjo

Antworten:

20

Sie können verwenden od, um Zahlen aus /dev/randomund zu erhalten /dev/urandom.

Zum Beispiel,

2 Byte vorzeichenlose Dezimalzahlen,

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

1 Byte vorzeichenbehaftete Dezimalzahl,

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

4 Byte vorzeichenlose Dezimalzahlen,

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

man odWeitere Informationen zu od.

EightBitTony
quelle
8

Einige Shells (z. B. bash(1)) haben eine $RANDOM"Variable", die Zufallszahlen angibt.

vonbrand
quelle
1

Sie könnten so etwas tun wie:

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

Was Ihnen auf einem 64-Bit-System so etwas wie Folgendes geben würde:

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
Stéphane Chazelas
quelle