GNU/Linux >> Belajar Linux >  >> Linux

Cara menghasilkan angka acak di shell BusyBox

$RANDOM dan od adalah fitur opsional di BusyBox, saya berasumsi bahwa pertanyaan Anda tidak termasuk dalam biner Anda. Anda menyebutkan dalam komentar bahwa /dev/urandom ada, itu bagus, artinya yang perlu Anda lakukan adalah mengambil byte darinya dalam bentuk yang dapat digunakan, dan bukan masalah yang jauh lebih sulit dalam mengimplementasikan generator bilangan acak. Perhatikan bahwa Anda harus menggunakan /dev/urandom dan bukan /dev/random , lihat Apakah rand dari /dev/urandom aman untuk kunci login?.

Jika Anda memiliki tr atau sed , Anda dapat membaca byte dari /dev/urandom dan buang semua byte yang bukan merupakan karakter yang diinginkan. Anda juga memerlukan cara untuk mengekstrak sejumlah byte dari aliran:baik head -c (membutuhkan FEATURE_FANCY_HEAD untuk diaktifkan) atau dd (membutuhkan dd untuk dikompilasi). Semakin banyak byte yang Anda buang, semakin lambat metode ini. Namun, menghasilkan byte acak biasanya lebih cepat dibandingkan dengan forking dan mengeksekusi binari eksternal, jadi membuang banyak byte tidak akan terlalu merugikan. Misalnya, cuplikan berikut akan menghasilkan angka acak antara 0 dan 65535:

n=65536
while [ $n -ge 65536 ]; do
  n=1$(</dev/urandom tr -dc 0-9 | dd bs=5 count=1 2>/dev/null)
  n=$((n-100000))
done

Perhatikan bahwa karena buffering, tr akan memproses beberapa byte lebih banyak daripada dd akan berakhir menjaga. tr BusyBox membaca bufferful (setidaknya 512 byte) sekaligus, dan membilas buffer outputnya setiap kali buffer input diproses sepenuhnya, sehingga perintah di atas akan selalu membaca setidaknya 512 byte dari /dev/urandom (dan sangat jarang lebih karena pengambilan yang diharapkan dari 512 byte masukan adalah 20 digit desimal).

Jika Anda memerlukan string unik yang dapat dicetak, buang saja karakter non-ASCII, dan mungkin beberapa karakter tanda baca yang mengganggu:

nonce=$(</dev/urandom tr -dc A-Za-z0-9-_ | head -c 22)

Dalam situasi ini, saya serius akan mempertimbangkan untuk menulis program C kecil khusus. Ini salah satu yang membaca empat byte dan menampilkan angka desimal yang sesuai. Itu tidak bergantung pada fungsi libc apa pun selain pembungkus untuk panggilan sistem read dan write , sehingga Anda bisa mendapatkan biner yang sangat kecil. Mendukung tutup variabel yang diteruskan sebagai bilangan bulat desimal pada baris perintah dibiarkan sebagai latihan; Anda akan dikenakan biaya ratusan byte kode (bukan sesuatu yang perlu Anda khawatirkan jika target Anda cukup besar untuk menjalankan Linux).

#include <stddef.h>
#include <unistd.h>
int main () {
    int n;
    unsigned long x = 0;
    unsigned char buf[4];
    char dec[11]; /* Must fit 256^sizeof(buf) in decimal plus one byte */
    char *start = dec + sizeof(dec) - 1;
    n = read(0, buf, sizeof(buf));
    if (n < (int)sizeof(buf)) return 1;
    for (n = 0; n < (int)sizeof(buf); n++) x = (x << 8 | buf[n]);
    *start = '\n';
    if (x == 0) *--start = '0';
    else while (x != 0) {
        --start;
        *start = '0' + (x % 10);
        x = x / 10;
    }
    while (n = write(1, start, dec + sizeof(dec) - start),
           n > 0 && n < dec + sizeof(dec) - start) {
        start += n;
    }
    return n < 0;
}

</dev/urandom sed 's/[^[:digit:]]\+//g' | head -c10

Linux
  1. Seberapa Besar Buffer Pipa?

  2. Bagaimana Cara Menampilkan Karakter Kontrol (^c, ^d, ^[, ...) Secara Berbeda Di Shell?

  3. CentOS / RHEL :Cara Mengubah shell login pengguna

  1. Tambahkan kolom angka di shell Unix

  2. Cara memeriksa apakah shell yang sedang berjalan adalah BusyBox

  3. Bagaimana cara menghitung jumlah byte dalam sebuah file, mengelompokkan byte yang sama?

  1. Bagaimana Membandingkan Angka dan String di Linux Shell Script

  2. Bagaimana Cara Menetapkan Output Perintah Ke Variabel Shell?

  3. Bagaimana Mendeteksi Jika Shell Dikendalikan Dari Ssh?