Combinando la salida leída del dispositivo /dev/random (generador de números aleatorios del kernel Linux) con tr y head, es posible generar diferentes tipos de cadenas de caracteres (strings) ya sea para utilizar en scripts, crear claves o contraseñas, o simplemente divertirse un rato (?)

He aquí algunos ejemplos.

Los archivos especiales de caracteres /dev/random y /dev/urandom proveen una interfaz al generador de números aleatorios del kernel Linux. Este generador recolecta ruido ambiental de controladores de dispositivos y otras fuentes para generar entropía, a partior de la cual se crean los números aleatorios. Al leer desde el archivo /dev/random, éste retorna bytes aleatorios de manera continua mientras disponga de bits en el pool de entropía. Si el pool se vacía, la salida se bloquea hasta que se recolecte ruido adicional. Esto ocurre de manera indefinida.

Sin embargo, a fin de generar cadenas de caracteres, necesitamos contar (preferentemente) con caracteres imprimibles o algún otro subconjunto de la tabla ASCII. Esto implica que es necesario filtrar la salida de /dev/random para quedarse sólo con aquellos bytes que corresponden al subconjunto de caracteres deseado. Para esto se puede recurrir a la herramienta tr.

tr simplemente traduce o elimina caracteres de un stream (entrada o salida estándar). Cuenta con un buen número de opciones para seleccionar ciertos subconjuntos de caracteres. Veamos directamente algunos ejemplos.

Supongamos que deseamos generar una cadena de 32 caracteres alfanuméricos aleatorios:

root@linuxito:~# cat /dev/random | tr -dc '[:alpha:]' | head -c 32; echo
WxmkWzRhGtVEDBRbXgbWpCTsfJgFZHvJ

La opción -d indica que se deben eliminar caracteres, mientras que la opción -c indica que se debe seleccionar el complemento del conjunto especificado (en este caso [:alpha:], es decir el conjunto de caracteres pertenecientes al alfabeto incluyendo mayúsculas y minúsculas). De esta forma, combinando las opciones -d y -c, la herramienta tr descarta todo byte que no corresponda a un caracter del alfabeto. Luego se utiliza head para cortar la salida luego de mostrar 32 bytes (opción -c).

Veamos más posibilidades...

  • [:alnum:] - Todas las letras y dígitos.
  • [:digit:] - Todos los dígitos.
  • [:print:] - Todos los caracteres imprimibles, incluyendo espacios.
  • [:graph:] - Todos los caracteres imprimibles, excepto espacios en blanco.
  • [:lower:] - Todas las letras minúsculas.
  • [:upper:] - Todas las letras mayúsculas.
  • [:punct:] - Todos los símbolos de puntuación.
  • [:xdigit:] - Todos los dígitos hexadecimales.
root@linuxito:~# cat /dev/random | tr -dc '[:alpha:]' | head -c 32; echo
cOjLwnJCaKBzbakxVdoLcuOUOVZSXeda
root@linuxito:~# cat /dev/random | tr -dc '[:alnum:]' | head -c 32; echo
4KJvHhLCBs5SaiqulgApTO3J12FdBs7L
root@linuxito:~# cat /dev/random | tr -dc '[:digit:]' | head -c 32; echo
69008080508702162919546284143137
root@linuxito:~# cat /dev/random | tr -dc '[:print:]' | head -c 32; echo
detPh0^jQy_ry3)se+>RlqiTeBW,^e`n
root@linuxito:~# cat /dev/random | tr -dc '[:graph:]' | head -c 32; echo
C}A79E7w'Z~MZ~3v{qTAb/o`0Ox%-upC
root@linuxito:~# cat /dev/random | tr -dc '[:lower:]' | head -c 32; echo
lrcqkennslznjsavxqweftvogguqbmks
root@linuxito:~# cat /dev/random | tr -dc '[:upper:]' | head -c 32; echo
SJZQSMSKDJHXMCONADIOGWWJMVKPSQDQ
root@linuxito:~# cat /dev/random | tr -dc '[:punct:]' | head -c 32; echo
./!_%"{&,.\=='!#|![%]'\|/};_+**|
root@linuxito:~# cat /dev/random | tr -dc '[:xdigit:]' | head -c 32; echo
cAb0597a8094E3F9EAc4eD927E24A7EE

Por supuesto también es posible definir nuestro propio conjunto de caracteres a filtrar:

root@linuxito:~# cat /dev/random | tr -dc 'abcd' | head -c 32; echo
ddcddcdddbddaacabacbbbadbdcdacac

Incluso definir rangos mediante el uso de guión del medio (-):

root@linuxito:~# cat /dev/random | tr -dc 'a-h' | head -c 32; echo
baagacgehdafeahbhbhbgfhhegdcgfde

Para mayor información y otras posibilidades, revisar las siguientes páginas de manual:

man 4 random
man tr
man head


Tal vez pueda interesarte


Compartí este artículo