Представлять Guid как набор целых чисел - PullRequest
3 голосов
/ 30 августа 2009

Если я хочу представить guid в виде набора целых чисел, как бы я обработал преобразование? Я думаю о том, как получить представление байта в массиве guid и разбить его на наименьшее возможное 32-битное целое число, которое можно преобразовать обратно в исходный guid. Примеры кода предпочтительнее ...

Кроме того, какой будет длина полученного целочисленного массива?

Ответы [ 5 ]

5 голосов
/ 30 августа 2009

Поскольку GUID составляет всего 16 байтов, вы можете преобразовать его в четыре целых числа:

Guid id = Guid.NewGuid();

byte[] bytes = id.ToByteArray();
int[] ints = new int[4];
for (int i = 0; i < 4; i++) {
   ints[i] = BitConverter.ToInt32(bytes, i * 4);
}

Обратное преобразование - это просто получение целых чисел в виде байтовых массивов и их объединение:

byte[] bytes = new byte[16];
for (int i = 0; i < 4; i++) {
   Array.Copy(BitConverter.GetBytes(ints[i]), 0, bytes, i * 4, 4);
}
Guid id = new Guid(bytes);
5 голосов
/ 30 августа 2009
  System.Guid guid = System.Guid.NewGuid();
    byte[] guidArray = guid.ToByteArray();

    // condition
    System.Diagnostics.Debug.Assert(guidArray.Length % sizeof(int) == 0);

    int[] intArray = new int[guidArray.Length / sizeof(int)];

    System.Buffer.BlockCopy(guidArray, 0, intArray, 0, guidArray.Length);


    byte[] guidOutArray = new byte[guidArray.Length];

    System.Buffer.BlockCopy(intArray, 0, guidOutArray, 0, guidOutArray.Length);

    System.Guid guidOut = new System.Guid(guidOutArray);

    // check
    System.Diagnostics.Debug.Assert(guidOut == guid);
4 голосов
/ 30 августа 2009

Каким-то образом мне было гораздо веселее делать это так:

byte[] bytes = guid.ToByteArray();
int[] ints = new int[bytes.Length / sizeof(int)];
for (int i = 0; i < bytes.Length; i++) {
    ints[i / sizeof(int)] = ints[i / sizeof(int)] | (bytes[i] << 8 * ((sizeof(int) - 1) - (i % sizeof(int))));
}

и обратное преобразование:

byte[] bytesAgain = new byte[ints.Length * sizeof(int)];
for (int i = 0; i < bytes.Length; i++) {
    bytesAgain[i] = (byte)((ints[i / sizeof(int)] & (byte.MaxValue << 8 * ((sizeof(int) - 1) - (i % sizeof(int))))) >> 8 * ((sizeof(int) - 1) - (i % sizeof(int))));
}
Guid guid2 = new Guid(bytesAgain);
2 голосов
/ 30 августа 2009

Не хватит ли встроенной структуры Guid?

Конструктор:

public Guid(
    byte[] b
)

А

public byte[] ToByteArray()

Который возвращает 16-элементный байтовый массив, содержащий значение этого экземпляра.

Упаковка байтов в целые числа и наоборот должна быть тривиальной.

1 голос
/ 30 августа 2009

Guid - это обычно 128-битное число.

- Правка

Таким образом, в C # вы можете получить 16 байтов через

byte[] b = Guid.NewGuid().ToByteArray();
...