Sử dụng / dev / ngẫu nhiên, / dev / urandom để tạo dữ liệu ngẫu nhiên


12

Tôi đang tìm cách để sử dụng /dev/random(hoặc /dev/urandom) từ dòng lệnh. Cụ thể, tôi muốn biết cách sử dụng một luồng như vậy stdinđể ghi các luồng số ngẫu nhiên thành stdout(một số trên mỗi dòng).

Tôi quan tâm đến các số ngẫu nhiên cho tất cả các loại số mà kiến ​​trúc của máy hỗ trợ nguyên bản. Ví dụ, đối với kiến ​​trúc 64 bit, các số này sẽ bao gồm các số nguyên có dấu và không dấu 64 bit và các số dấu phẩy động 64 bit. Theo phạm vi, phạm vi tối đa cho các loại số khác nhau sẽ làm.

Tôi biết cách thực hiện tất cả điều này với các trình thông dịch đa năng như Perl, Python, v.v., nhưng tôi muốn biết cách thực hiện điều này với các công cụ "đơn giản hơn" từ trình bao. (Theo "đơn giản hơn", ý tôi là "nhiều khả năng sẽ khả dụng ngay cả trong bản cài đặt Unix rất tối thiểu".)

Về cơ bản vấn đề làm giảm việc chuyển đổi dữ liệu nhị phân thành biểu diễn chuỗi của chúng trên dòng lệnh. (Ví dụ, điều này sẽ không làm : printf '%f\n' $(head -c8 /dev/random).)

Tôi đang tìm kiếm câu trả lời không rõ ràng. Ngoài ra, sự khác biệt giữa /dev/random/dev/urandomkhông quan trọng đối với câu hỏi này. Tôi hy vọng rằng bất kỳ thủ tục nào hoạt động cho cái này sẽ hoạt động cho cái kia, ngay cả khi ngữ nghĩa của kết quả có thể khác nhau.


Tôi đã điều chỉnh câu trả lời của EightBitTony để tạo ra các hàm toints, v.v. được hiển thị bên dưới.

Ví dụ sử dụng:

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

Nhận xét:

  1. Tôi đang sử dụng hexdumpthay odvì bởi vì nó cho tôi một cách dễ dàng hơn để định dạng đầu ra theo cách tôi muốn;
  2. Mặc dù khó chịu, hexdumpkhông hỗ trợ số nguyên 64 bit (wtf ???);
  3. Giao diện chức năng nhu cầu công việc (ví dụ như họ nên chấp nhận -n5cũng như -n 5), nhưng với tội nghiệp lập trình shell skillz của tôi, đây là tốt nhất mà tôi có thể đặt lại với nhau một cách nhanh chóng. (Bình luận / cải tiến chào mừng, như mọi khi.)

Điều ngạc nhiên lớn mà tôi có được từ bài tập này là phát hiện ra việc lập trình trên vỏ các công cụ số cơ bản nhất khó như thế nào (ví dụ đọc một số thập lục phân hoặc lấy giá trị float gốc tối đa) ...


_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/urandomchỉ cung cấp cho bạn số nguyên.
cuonglm

theo như tôi biết, / dev / ngẫu nhiên không tạo ra các số ngẫu nhiên trên mỗi se, nhưng thêm nhiễu vào các hàm toán học cung cấp số giả ngẫu nhiên để chúng trở nên ít dự đoán hơn. Bạn có thể muốn xem Randomlib.sourceforge.net
Rui F Ribeiro


Bạn có cần sự ngẫu nhiên về chất lượng của tiền điện tử hay không, ví dụ như gieo hạt dựa trên thời gian đủ tốt?
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: động lực cho câu hỏi của tôi là tìm hiểu nhiều hơn về các công cụ shell và Unix hơn là về tính ngẫu nhiên; Tôi chỉ muốn biết những công cụ Unix cơ bản nào tồn tại để chuyển đổi một luồng dữ liệu nhị phân thành biểu diễn chuỗi của chúng.
kjo 11/03/2016

Câu trả lời:


21

Bạn có thể sử dụng odđể lấy số ra /dev/random/dev/urandom.

Ví dụ,

Số nguyên thập phân không dấu 2 byte,

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

Số nguyên thập phân được ký 1 byte,

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

Số nguyên thập phân không dấu 4 byte,

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

man odđể biết thêm thông tin về od.


8

Một số shell (ví dụ bash(1)) có $RANDOM"biến" cho số ngẫu nhiên.


1

Bạn có thể làm một cái gì đó như:

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

Mà trên hệ thống 64 bit sẽ cung cấp cho bạn một cái gì đó như:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.