GNU/Linux >> Znalost Linux >  >> Linux

Jak generovat náhodná čísla v prostředí BusyBox

$RANDOM a od jsou volitelné funkce v BusyBox, předpokládám vzhledem k vaší otázce, že nejsou zahrnuty ve vašem binárním souboru. V komentáři uvádíte, že /dev/urandom je přítomen, to je dobře, to znamená, že z něj musíte získat bajty v použitelné formě, a ne mnohem obtížnější problém implementace generátoru náhodných čísel. Všimněte si, že byste měli použít /dev/urandom a ne /dev/random , viz Je rand z /dev/urandom bezpečný pro přihlašovací klíč?.

Pokud máte tr nebo sed , můžete číst bajty od /dev/urandom a zahoďte jakýkoli bajt, který není žádoucí znak. Budete také potřebovat způsob, jak extrahovat pevný počet bajtů ze streamu:buď head -c (vyžaduje FEATURE_FANCY_HEAD být povolen) nebo dd (vyžaduje dd ke zkompilování). Čím více bajtů zahodíte, tím pomalejší bude tato metoda. Generování náhodných bajtů je však obvykle poměrně rychlé ve srovnání s forkingem a spouštěním externích binárních souborů, takže vyřazení velkého množství z nich nebude moc bolet. Například následující fragment vytvoří náhodné číslo mezi 0 a 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

Všimněte si, že kvůli ukládání do vyrovnávací paměti tr zpracuje o několik bajtů více než dd nakonec udrží. BusyBox je tr čte vyrovnávací paměť (alespoň 512 bajtů) najednou a vyprázdní její výstupní vyrovnávací paměť vždy, když je vstupní vyrovnávací paměť plně zpracována, takže příkaz výše vždy načte alespoň 512 bajtů z /dev/urandom (a velmi zřídka více, protože očekávaný odběr z 512 vstupních bajtů je 20 dekadických číslic).

Pokud potřebujete jedinečný tisknutelný řetězec, vyhoďte jiné znaky než ASCII a možná i některé nepříjemné interpunkční znaky:

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

V této situaci bych vážně uvažoval o napsání malého, vyhrazeného C programu. Zde je jeden, který přečte čtyři bajty a vydá odpovídající desetinné číslo. Nespoléhá se na žádnou jinou funkci knihovny libc než na obaly pro systémová volání read a write , takže můžete získat velmi malou binární hodnotu. Podpora proměnné cap předaná jako celé desítkové číslo na příkazovém řádku je ponechána jako cvičení; bude vás to stát stovky bajtů kódu (není něco, o co byste se museli starat, pokud je váš cíl dostatečně velký na to, aby provozoval 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. Jak velký je Pipe Buffer?

  2. Jak zobrazit řídicí znaky (^c, ^d, ^[, …) odlišně v shellu?

  3. Jak zjistit, zda je Shell řízen z Ssh?

  1. Jak nabootovat KVM Guest do záchranného shellu

  2. Jak získat PYTHONPATH v shellu?

  3. Jak zkontrolovat, zda je aktuálně spuštěný shell BusyBox

  1. Jak porovnávat čísla a řetězce ve skriptu Linux Shell

  2. Jak vygenerovat náhodné heslo v linuxu pomocí /dev/random

  3. Jak spočítat počet bajtů v souboru seskupením stejných bajtů?