$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