zeros newguid new length genera example all c#

length - system guid newguid c#



Cómo generar enteros únicos basados en GUID (9)

Aquí está la manera más simple:

Guid guid = Guid.NewGuid(); Random random = new Random(); int i = random.Next();

Notarás que el guid no se usa aquí, principalmente porque no tendría sentido usarlo. El algoritmo GUID de Microsoft ya no usa la dirección MAC de la computadora: los GUID se generan con un generador pseudoaleatorio (basado en valores de tiempo), por lo que si desea un entero aleatorio, tiene más sentido usar la clase Random para esto.

Actualización: en realidad, usar un GUID para generar un int probablemente sería peor que usar Random ("peor" en el sentido de que esto generaría colisiones). Esto se debe a que no todos los 128 bits en un GUID son aleatorios. Lo ideal sería excluir los bits no variables de una función de hashing, aunque sería mucho más fácil generar un número aleatorio, como creo que mencioné antes. :)

¿Es posible generar un entero único (altamente probable) a partir de los GUID?

int i = Guid.NewGuid().GetHashCode(); int j = BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0);

¿Cuál es mejor?


Debido a que el espacio GUID es mayor que el número de enteros de 32 bits, se garantiza que tendrá colisiones si tiene suficientes GUID. Dado que usted comprende eso y está preparado para enfrentar colisiones, aunque sea raro, GetHashCode () está diseñado exactamente para este propósito y debería preferirse.


En una clase estática, conserve un entero constante const, luego agregue 1 a él antes de cada acceso individual (usando una propiedad public get). Esto asegurará que recorra todo el rango int antes de obtener un valor no exclusivo.

/// <summary> /// The command id to use. This is a thread-safe id, that is unique over the lifetime of the process. It changes /// at each access. /// </summary> internal static int NextCommandId { get { return _nextCommandId++; } } private static int _nextCommandId = 0;

Esto producirá un valor entero único dentro de un proceso en ejecución. Como no define explícitamente cuán único debe ser su número entero, esto probablemente corresponda.


Eric Lippert hizo una publicación muy interesante (como siempre) sobre la probabilidad de colisiones hash .

Deberías leerlo todo, pero él concluyó con este gráfico muy ilustrativo:

En relación con tu pregunta específica, también iría con GetHashCode ya que las colisiones serán inevitables de cualquier manera.


La función GetHashCode está específicamente diseñada para crear un rango bien distribuido de enteros con baja probabilidad de colisión, por lo que para este caso de uso es probable que sea lo mejor que puede hacer.

Pero, como estoy seguro de que sabe, el almacenamiento de 128 bits de información en 32 bits arroja una gran cantidad de datos, por lo que seguramente habrá colisiones si tiene un número suficientemente grande de GUID.


Si está buscando romper la barrera 2 ^ 32, intente con este método:

/// <summary> /// Generate a BigInteger given a Guid. Returns a number from 0 to 2^128 /// 0 to 340,282,366,920,938,463,463,374,607,431,768,211,456 /// </summary> public BigInteger GuidToBigInteger(Guid guid) { BigInteger l_retval = 0; byte[] ba = guid.ToByteArray(); int i = ba.Count(); foreach (byte b in ba) { l_retval += b * BigInteger.Pow(256, --i); } return l_retval; }

El universo se reducirá a una extensión fría y oscura antes de experimentar una colisión.



Tenía un requisito en el que se necesitaban varias instancias de una aplicación de consola para obtener una ID entera única. Se usa para identificar la instancia y se asigna al inicio. Debido a que el .exe se inicia con las manos, establecí una solución usando los tics de la hora de inicio.

Mi razonamiento era que sería casi imposible para el usuario iniciar dos .exe en el mismo milisegundo. Este comportamiento es determinista: si tiene una colisión, sabe que el problema fue que se iniciaron dos instancias al mismo tiempo. Los métodos que dependen de hashcode, GUID o números aleatorios pueden fallar de maneras impredecibles.

Configuré la fecha en 0001-01-01, agregué la hora actual y dividí las marcas en 10000 (porque no configuré los microsegundos) para obtener un número lo suficientemente pequeño como para caber en un número entero.

var now = DateTime.Now; var zeroDate = DateTime.MinValue.AddHours(now.Hour).AddMinutes(now.Minute).AddSeconds(now.Second).AddMilliseconds(now.Millisecond); int uniqueId = (int)(zeroDate.Ticks / 10000);

EDITAR: hay algunas advertencias. Para hacer que las colisiones sean poco probables, asegúrese de que:

  • Las instancias se inician manualmente (más de un milisegundo de diferencia)
  • La ID se genera una vez por instancia, al inicio
  • La ID solo debe ser única con respecto a otras instancias que se están ejecutando actualmente
  • Solo se necesitará una pequeña cantidad de ID.