viernes, 22 de julio de 2016

Tareas Comunes con Números en C# - Parte 5/5 | Clase Random

Índice

1. Introducción
2. Palabras Clave
3. Clase Random
3.1 Generalidades
3.2 Creación de instancias
3.3 Métodos comunes
3.4 Criptografía
4. Conclusiones
5. Literatura & Enlaces

1. Introducción

Para operaciones con números aleatorios, en .NET Framework se cuenta con la clase Random. Esta clase facilita al programador la generación no sólo de valores enteros aleatorios, sino además decimales y bytes. Este último artículo de la serie Tareas Comunes con Números en C#, describe tanto el uso de esta tipo de dato como buenas prácticas a tener en cuenta a la hora de instanciar objetos; al final se presenta una alternativa para la generación segura de valores pseudoaleatorios seguros para aplicaciones de criptografía.

2. Palabras Clave

  • Criptografía
  • Pseudoaleatorio
  • Random

3. Clase Random

3.1 Generalidades

La clase Random es un elemento de programa que actúa como un artefacto generador de números pseudoaleatorios. De acuerdo con "Random Class" (2016), la clase Random ha sido diseñado teniendo en cuenta los requerimientos estadísticos para la generación aleatoria de secuencias de números.

Los valores de los tipos de datos q ue genera esta clase comprende bytes, integers y doubles (Albahari, 2012).

3.2 Creación instancias

Una instancia de la clase puede ser creada usando el constructor predeterminado (i.e., sin argumentos) o especificando una semilla (seed).

Las siguientes líneas de código demuestran que la especificación de un valor de semilla para dos instancias de Random, garantiza la reproducibilidad de valores aleatorios: 

// Reproducibilidad de valores aleatorios:
var aleatorio1 = new Random(1);
var aleatorio2 = new Random(1);

Console.WriteLine(aleatorio1.Next(100) + ", " + aleatorio1.Next(100)); // 24, 11
Console.WriteLine(aleatorio2.Next(100) + ", " + aleatorio2.Next(100)); // 24, 11

En caso contrario, es decir sin reproducibilidad de valores, usar el constructor predeterminado. De ser así, la clase Random usa la hora actual del sistema para la instanciación. Sin embargo, el programador debe tener presente la advertencia dada en Albahari (2012)
"Because the system clock has limited granularity, two Random instances created close together (typically within 10 ms) will yield the same sequence of values."
Esto indica al programador que instancias creadas en deltas de tiempos muy ínfimos es análogo a crear dos instancias con la misma semilla (como el ejemplo de código de arriba).

Además se advierte: 
"A common trap is to instantiate a new Random object every time you need a random number, rather than reusing the same object."
Lo cual sugiere reutilizar una instancia en particular en lugar de crear una nueva cada vez que sea necesario. Aún así, en Albahari (2012) se aclara este punto inclusive más: 
"A good pattern is to declare a single static Random instance. In multithreaded scenarios, however, this can cause trouble because Random objects are not thread-safe."
Así que el programador debe mantener esta precaución con operaciones distribuidas en distintos threads que acceden a una única instancia static Random, en caso de omitirlase pueden obtener resultados inconsistentes.

3.3 Métodos comunes

Random cuenta con los siguientes métodos: 
Métodos clase Random
Figura 1. Métodos clase Random ("Random Class", 2016).
Aquí se puede ilustrar el uso del métodos NextDouble

var aleatorio = new Random();

Console.WriteLine(aleatorio.NextDouble());

En la salida estándar se produce el siguiente resultado: 

0.467010679872246

NextDouble genera un valor numérico double entre 0 y 1.

3.4 Criptografía

En Albahari (2012) anuncian que la funcionalidad de Random no se considera apropiada para alto nivel de seguridad, como en el caso de criptografía. En su lugar, Microsoft .NET Framework provee un generador de números aleatorios criptográficamente más robusto y seguro.

Del generador al que se hace referencia reside en el namespace System.Security.CryptographyEl programador puede conocer su uso a través de este ejemplo: 

// Generador pseudoaleatorio seguro:
var aleatorioSeguro = RandomNumberGenerator.Create();
byte[] bytes = new byte[32];
aleatorioSeguro.GetBytes(bytes);

Con este código sólo se crea la representación del número pseudoaleatorio como un arreglo de bytes. En el caso de requerirse una representación legible, este código permite obtener un valor entero a través de la clase BitConverter [Otros Mecanismos de Conversión en C#/4: Clase BitConverter]

// Obtención de entero a través de BitConverter:
byte[] b = new byte[4];
aleatorioSeguro.GetBytes(b);
int i = BitConverter.ToInt32(bytes, 0);

Console.WriteLine(i.ToString());

Resultado en la salida estándar de LINQPad

98007634

4. Conclusiones

Se comprendió cómo usar la clase Random para la generación de valores enteros, punto flotantes y bytes de modo aleatorio. Entre sus funciones estudiadas esta la reproducibilidad de valores aleatorios para experimentos, generación de valores aleatorios como decimales. Al final se advirtió que la implementación de Random no es útil para un alto nivel de seguridad en aplicaciones de seguridad; como criptografía.

La siguiente serie se enfoca en el estudio de enumeraciones en C#.

5. Literatura & Enlaces

Albahari, J., Albahari, B. (2012). C# 5.0 in a Nutshell. United States: O'Reilly Media.
Random Class (System) (2016, julio 22). Recuperado desde: https://msdn.microsoft.com/en-us/library/system.random.aspx
Otros Mecanismos de Conversión en C#/4: Clase BitConverter (2016, junio 22). Recuperado desde: https://ortizol.blogspot.com/2016/07/otros-mecanismos-de-conversion-en-csharp-parte-4-4-clase-bitconverter.html


O

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.