UUID генератор проблема - PullRequest
       14

UUID генератор проблема

1 голос
/ 25 марта 2011

У меня есть класс uuid, который является частью переносимой библиотеки, которая инициализируется следующим фрагментом кода. Он работает нормально под Windows, но под Linux это неправильно генерирует UUID.

uint32 data[4];
data[0] = rng.Get();
data[1] = rng.Get();
data[2] = rng.Get();
data[3] = rng.Get();

data[1] = (data[1] & 0xffffff0f) | 0x40;
data[2] = (data[2] & 0x7fffffff) | 0x40000000;

printf("12345678901234567890123456789012\n");   
memcpy(uuid, data, 16);


for (int i = 0; i < 4; i++)
    printf("%04X", data[i]);
printf("\n");

for (int i = 0; i < 16; i++)
    printf("%02X", uuid[i]);
printf("\n");

Операторы printf - это моя отладка.

Но цифры запутались. Почему нижние 4 байта пусты? И почему печатается первый uuid, отличный от последнего?

Платформа - это 64-битный Linux на x86. Это всегда будет выполняться на архитектуре x86 с прямым порядком байтов.

например. образец вывода

1st run
12345678901234567890123456789012
B6D2ADAF46CF624A581187F3670BBEE0
AFADD2B6D6E792FB4A62CF4600000000  // why is this different from the previous no?. also the last 4 bytes not set???


2nd run
12345678901234567890123456789012
96D6D234D5602743548FD812A0D96818
34D2D6965B65F32F432760D500000000 // same problem as earlier

Что-то идет не так с преобразованием.

Теперь это решено. Мне нет дела до порядка байтов. В любом случае байты случайны!

Ответы [ 5 ]

4 голосов
/ 25 марта 2011

Похоже, что спецификатор %X ожидает ввода размером int, в то время как вы, похоже, передаете ему unsigned char (не правда ли, что такое uuid[i]?).

Попробуйте сделать это и посмотрите, поможет ли это:

for (int i = 0; i < 16; i++) {
    int temp = uuid[i];
    printf("%02X", temp);
}
printf("\n");

Обновление - Новая теория

Хорошо, я внимательно посмотрел на него после прочтения ответа Мэтью.

Проблема memcpy вместе с (неизвестным) типом uuid. Вы копируете uint s поверх uuid. Первые 4 байта uuid, как и следовало ожидать, являются младшим порядковым представлением data[0].

Теперь одна теория, которая могла бы объяснить остальное, состоит в том, что uint32 на самом деле имеет длину 8 байтов вместо 4, поэтому, когда вы копируете первые 16 байтов data в uuid, мы видим в следующем порядке:

  • 4 LSB data[0], little-endian
  • 4 MSB data[0] (мусор)
  • 4 LSB data[1], порядковый номер
  • 4 MSB data[1] (мусор, почему-то все нули)
  • И ничего из data[2] и data[3].

Так что же sizeof(uint32) равно?

1 голос
/ 25 марта 2011

Первые 4 байта data и uuid совпадают, но в обратном порядке - похоже на проблему с порядком байтов.

  • Это связано с тем, что printf печатает каждый uint32 как одинблок, но символы (без знака?) в порядке следования памяти.

2-ий 4 байта data и 3-ий 4 байта uuid также одинаковы, но обращены.Аналогичная проблема.

Решите эти две проблемы, а остальные, вероятно, встанут на свои места.

0 голосов
/ 25 марта 2011

uint32 - это не 32 бита в 64-битной ОС, а 64 бита. Я видел это здесь , но я думаю, что это верно для всех 64-битных систем.

0 голосов
/ 25 марта 2011

Здесь происходят две вещи:

  1. проблема с порядком байтов
  2. вы находитесь на 64-битной машине, поэтому компилятор выравнивает (32-битные) целые числа с собственным словом

В общем, вы не можете предположить, как компилятор размещает вещи в памяти.Вы должны сделать это по старинке: uuid [0] = data [0] >> 24 & 0xFF

0 голосов
/ 25 марта 2011

Попробуйте вместо этого отладку

for (int i = 0; i < 4; i++)
    printf("%04X ", data[i]);
printf("\n");

for (int i = 0; i < 16; i++)
    printf("%02X ", uuid[i]);
printf("\n");

Я только что добавил пробел после X.

...