¿Qué tan aleatorio es lo aleatorio?

En los sistemas Unix, los números aleatorios se generan de diversas maneras y los datos aleatorios pueden tener múltiples propósitos. Desde simples comandos hasta procesos bastante complejos, vale la pena preguntarse: "¿Qué tan aleatorio es lo aleatorio?.

Haciendo números aleatorios simples

Si lo único que necesitas es una lista informal de números aleatorios, la variable RANDOM es una opción sencilla:

echo $RANDOM

Obtendrás un número entre 0 y 32767 este último es el número más grande que se puede obtener con dos bytes.

En realidad lo que obtendremos es un número "pseudoaleatorio". Como bien saben quienes piensan con frecuencia en los números aleatorios, los números generados por un programa tienen limitaciones. Los programas siguen pasos meticulosamente diseñados, y estos pasos distan mucho de ser verdaderamente aleatorios. Se puede aumentar la aleatoriedad del valor de RANDOM inicializándolo, es decir, asignarle a la variable un valor de partida. Algunos simplemente utilizan el ID del proceso actual (mediante $$) para ello. Cabe destacar que, para cualquier punto de partida, los valores subsiguientes que proporciona $RANDOM son más bien predecibles:

$ RANDOM=$$;echo $RANDOM; echo $RANDOM;echo $RANDOM
7424
28301
30566
$ RANDOM=$$;echo $RANDOM; echo $RANDOM;echo $RANDOM
7424
28301
30566

Si necesitas números aleatorios menos predecibles, quizá puedas usar otro valor inicial (semilla) que funcione mejor:

$ RANDOM=`date +%s`;echo $RANDOM;echo $RANDOM;echo $RANDOM
32077
1397
32029
$ RANDOM=`date +%s`;echo $RANDOM;echo $RANDOM;echo $RANDOM
16116
16487
11588

Aquí estamos usando el número de segundos transcurridos desde el nacimiento de UNIX (1 de enero de 1970 las 00:00:00 utc).

Existe otro comando para generar números pseudoaleatorios que se llama "shuf". En el comando siguiente, generamos 10 números entre 0 y 32767. Este comando debe comenzar cada secuencia con un número diferente, no es necesario inicializarlo.

$ shuf -i 0-32767 -n 10
32157
16611
24087
28301
9088
4662
12780
30518
7549
12830

Aleatorios más complejos

Para necesidades más exigentes de datos aleatorios, como su uso en cifrado, se emplean datos verdaderamente aleatorios. Los archivos "/dev/random" y "/dev/urandom" superan la predictibilidad de la programación al utilizar ruido ambiental recopilado de controladores de dispositivos y de otras fuentes del sistema, almacenándolo en un "reservorio de entropía".

La generación de números pseudoaleatorios, a menudo llamada "PRNG", utiliza en sistemas Unix dos archivos. Desde la línea de comandos, estos archivos tienen el siguiente aspecto:

crw-rw-rw- 1 root root 1, 8 Jun 18 13:24 random
crw-rw-rw- 1 root root 1, 9 Jun 18 13:24 urandom

Como la mayoría, sino es que todos los archivos en /dev, estos archivos tienen longitud cero y, al igual que /dev/null, proporcionan un servicio especial que no resulta evidente al consultar el listado de archivos. Los archivos /dev/random y /dev/urandom se pueden usar para generar números que se aproximan a valores aleatorios, y los números aleatorios son fundamentales para cifrar el contenido y evitar que sea predecible.

Con el comando "stat", se obtiene información más detallada de un archivo. Aquí esta lista de "/dev/urandom". Observe que tiene longitud cero y las marcas de fecha. Este archivo se generó la última vez que se inició el sistema.

$ stat /dev/urandom
  File: /dev/urandom
  Size: 0               Blocks: 0          IO Block: 4096
character special file
Device: 6h/6d   Inode: 1056        Links: 1     Device type:
1,9
Access: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (
0/    root)
Access: 2017-07-15 13:24:49.719736172 -0400
Modify: 2017-07-15 13:24:49.719736172 -0400
Change: 2017-07-15 13:24:49.719736172 -0400
 Birth: -

Examinando la entropía

Para hacerse una idea de la cantidad de entropía disponible en un sistema, puede consultar el archivo especial llamado "entropyavail", más precisamente /proc/sys/kernel/random/entropyavail. Tenga en cuenta que este archivo reside en el sistema de archivos /proc, un sistema de archivos relacionado con el kernel y los procesos de ejecución, y no con los sistemas de archivos habituales. El archivo entropy_avail parecerá vacío, pero al visualizar su contenido se obtendrá información:

-r--r--r-- 1 root root 0 Jul 15 16:01 entropy_avail

Para hacerse una idea de la cantidad de datos pseudoaleatorios disponibles en tu "reservorio de entropía", puedes ejecutar el siguiente comando:

cat /proc/sys/kernel/random/entropy_avail
2684

El resultado representa la cantidad de bits de entropía acumulados. Puede parecer poco en un mundo donde solemos hablar de terabytes, pero números superiores a 100 son un una buena señal. Además, este número cambi con frecuencia pues es acumulable. Si lo revisas tres o más veces seguidas, podría ser que el valor cambie:

$ cat /proc/sys/kernel/random/entropy_avail
2683
$ cat /proc/sys/kernel/random/entropy_avail
2684
$ cat /proc/sys/kernel/random/entropy_avail
2493

Ambos archivos "/dev/random" y "/dev/urandom/ van consumiendo la reserva de entroía y funcionan de forma prácticamente idéntica, salvo una diferencia importante: /dev/random se bloquea al agotarse la entropía y podría detener un proceso, mientras que /dev/urandom nunca se bloquea, pero tendría menos entropía. El archivo /dev/urandom parece ser una opción más utilizada actualmente.

Aleatoriedad vs. Entropía

Ahora que hemos mencionado la entropía, analicemos la relación entre los términos. Si bien están estrechamente ligados, no significan lo mismo. La entropía se asemeja al lanzamiento de una moneda y mide la incertidumbre del resultado, mientras que la aleatoriedad se relaciona con una distribución probabilística. En el ámbito informático, a menudo se utilizan como si fueran sinónimos.

Generar archivos con contenidos aleatorios

Si se necesita, se puede crear un archivo con datos pseudoaleatorios. Con el siguiente comando creamos un archivo de 1 Gigabyte llamado "mi_vida" y luego podemos examinar el contenido de la primera línea utilizando el comando "od" para hacernos una idea de lo creado:

$ head -c 1G < /dev/urandom > myfile

Revisando el archivo

$ ls -l myfile
-rw-rw-r-- 1 shs shs 1073741824 Jul 14 15:10 myfile
$ head -1 myfile | od -bc
0000000 210 365 102 233 332 203 075 262 302 064 255 110 265
372 365 176
        210 365   B 233 332 203   = 262 302   4 255   H 265
372 365   ~
0000020 274 243 116 012
        274 243   N  \n

Generando números aleatorios

Puedes usar /dev/random para generar números pseudoaleatorios en la línea de comandos:

$ od -vAn -N4 -tu < /dev/urandom
 2760998497

Usando comandos como este que utilizan /dev/random y od para procesarlo, pueden generar números casi... casi aleatorios. Si ejecutas el mismo comando varias veces recibirás distintos valores.

Las opciones de estos comandos son interesantes. La opción -N controla el tamaño de la salida en bytes. Por ejemplo, -N4 significa que el número resultante tendrá cuatro bytes. Esto no significa que el número resultante no pueda ser pequeño, como 12; simplemente que ocupará cuatro bytes. Los números más grandes que verá tendrán diez dígitos. Si cambia a -N5, obtendrá dos números: uno de 4 bytes y otro de 1. Si omite la opción -N, obtendrá una secuencia continua de números, al menos hasta que se canse de verlos y pulse Ctrl+C.

$ od -vAn -tu < /dev/urandom
 2860283906 3419549082 3207848245 2737687912
 1333710913  933348251 2572772980 1418852288
 3788708580  870673152 4083922259 1506538622
 3772099425 3296232922  692742105  818767715
 3576300418 2497391372 3756319951 1357979412
 1588018330  740469378 3140770678  958473449
  187769983  168320294  393843609 3925659647
 1320592631 3858359323 1435946222 2841928818
   99971705 1732928020 2292358742 2367929537

Si haces lo mismo con /dev/random, es probable que te quedes sin recursos bastante rápido.

$ od -vAn -tu < /dev/random
  897129786 2714319998 1496103441 4272099144
   99601145 3584433910 2759928205  817917225
 1692688250 3711124362  787695563 2107932582
  427417199 3136902189 1527656210 2881971698
 3895588188 1111869233 1024834659 3486503580
 4184363003 3255228299  634631930 2477891792
^Z
[1]+  Stopped                 od -vAn -tu < /dev/random

Ten en cuenta que Ctrl+Z se usa para suspender procesos cuando se bloquea la linea de comandos. El "repositorio de entropía" se agota y se tiene que regenerar.

Más allá de /dev/urandom

Dadas las limitaciones de /dev/random y /dev/urandom existen otras opciones. Actualmente hay más de una docena de generadores de números aleatorios por hardware, también llamados "Generadores de números aleatorios verdaderos", o conocidos como "TRNG". Además, la "Entropía como Servicio" (EaaS) es una opción que podría cambiar drásticamente la naturaleza de la aleatoriedad en los sistemas que se utilizan.

La NIST (National Institute of Standards and Technology) tiene un documento al respecto del EAAS:

https://web.archive.org/web/20170723130801/http://csrc.nist.gov/projects/eaas/

Traducción

Del original: https://web.archive.org/web/20170719154624/https://www.networkworld.com/article/3208389/linux/unix-how-random-is-random.html

Por emilio (Cualquier comentario a emilio arroba texto-plano.xyz)


Regresar al índice

Este espacio es posible gracias a la comunidad texto-plano.xyz.