Gerando arquivos com números ASCII usando / dev / urandom?

5

Como posso gerar arquivos de 10 MB a partir de /dev/urandom preenchidos com:

  • ASCII 1s e 0s

  • Números ASCII entre 0 e 9

por programings 19.08.2014 / 15:26

2 respostas

6
  • Números ASCII entre 0 e 9

    < /dev/urandom tr -dc '[:digit:]' | head -c 10000000 > 10mb.txt
    
  • ASCII 1s e 0s

    < /dev/urandom tr -dc 01 | head -c 10000000 > 10mb.txt
    
por 19.08.2014 / 15:43
5

Se você considerar que o valor real de cada byte recebido de </dev/urandom é significativo apenas por representar uma ocorrência de probabilidade bem-sucedida do valor desse byte, conforme determinado pelo PRNG, você perceberá se um Byte de entrada corresponde ao valor para o que você está procurando não é tão importante quanto quantas vezes ele faz. Se o PRNG for bom, então qualquer byte no espectro ASCII deve ter 1/256 de chance de ocorrer para cada byte lido.

Se você deseja restringir esse espectro a algum subconjunto ASCII, a maneira mais eficiente de lidar com isso é ampliar simultaneamente a chance de ocorrência desses caracteres em seu subconjunto e remover as chances de qualquer outro. tr é muito bom nisso, pois permite converter caracteres em um intervalo especificado em tantas ocorrências de um caractere substituto. Assim:

d=$(printf '[%d*25]' 1 2 3 4 5 6 7 8 9)
</dev/urandom LC_ALL=C tr '
LC_ALL=C </dev/urandom \
tr '
TR PIPELINE | dd bs=4k count=2560
-7' "[
d=$(printf '[%d*25]' 1 2 3 4 5 6 7 8 9)
</dev/urandom LC_ALL=C tr '
LC_ALL=C </dev/urandom \
tr '
TR PIPELINE | dd bs=4k count=2560
-7' "[%pre%*5]$d[0*]" | tr -d \0
-7' "$d[0*]"
*5]$d[0*]" | tr -d \0
-7' "$d[0*]"

Há algumas coisas acontecendo, e elas são:

  1. d=[[char]*[num]]...

    • aqui eu apenas configurei uma var contendo o segundo argumento que eu quero entregar tr na próxima linha. Cada [] valor entre colchetes é um destino de conversão para tr e cada *25 representa quantos membros de um intervalo na ordem especificada no primeiro argumento de tr devem direcionar esse caracter para conversão.
  2. LC_ALL=C

    • Isto (importante) manda que todo byte lido deva ser interpretado como um byte ASCII, e assim todos bytes lidos será qualquer de NUL por meio de octal 7 .
  3. 'tr-7' "$d[0*]"

    • instrui $d a converter todos os bytes de entrada de acordo com o valor em -- . Isso significa que os bytes tr (ou os primeiros 25 bytes no intervalo) são convertidos em uns, %code% em pares e assim por diante.

O resultado é que toda entrada é convertida em apenas dígitos através de uma (quase) distribuição uniforme de aleatoriedade - e então todo byte é usado, mas todos acabam sendo apenas os que você quer. Com o exemplo acima, no entanto, há uma chance 4% maior de que um 0 ocorrerá na saída de %code% do que qualquer outro dos bytes. Se isso é um problema, você também pode fazer:

%pre%

... que resolve esse problema.

Agora, para os 10 milhões, isso funcionará:

%pre%     
por 25.03.2015 / 04:24

Tags