Neil Fenwick ma rację. Jednak możemy wykorzystać tę strukturę na naszą korzyść.
Wersja 4 (.Net)
Wersja 4 UUID używać schematu polegając tylko na liczb losowych. Algorytm ten ustawia numer wersji oraz dwa zarezerwowane bity. Wszystkie inne bity są ustawiane przy użyciu losowego lub pseudolosowego źródła danych. UUID w wersji 4 mają postać xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx gdzie x jest dowolną cyfrą szesnastkową, a y jest jedną z 8, 9, A lub B. f47ac10b-58cc-4372-a567-0e02b2c3d479.
użyć wersji Pole
Jesteśmy wolni, aby zmienić pierwszy półbajt bajtu 8; więc jeśli masz mniej niż 17 maszyn, możesz je zidentyfikować, zmieniając identyfikatory GUID utworzone na każdym z nich.
static Guid NewSystemGuid(int machine)
{
if (machine < 0 | machine > 0xF)
throw new ArgumentOutOfRangeException("machine");
var g = Guid.NewGuid();
var arr = g.ToByteArray();
arr[7] = (byte)((machine << 4) | (arr[7] & 0xF));
return new Guid(arr);
}
static int ExtractMachine(Guid guid)
{
var arr = guid.ToByteArray();
return (arr[7] >> 4) & 0xF;
}
użyć wersji Field i „Y”
Nie jestem pewien, czy zmieniając Y zmienią unikalność identyfikatora GUID, więc może się wahać. Jeśli masz mniej niż 17 maszyn, pozostań przy pierwszym rozwiązaniu.
static Guid NewSystemGuid(int machine)
{
if (machine < 0 | machine > 0xFF)
throw new ArgumentOutOfRangeException("machine");
var m1 = machine & 0xF;
var m2 = (machine >> 4) & 0xF;
var g = Guid.NewGuid();
var arr = g.ToByteArray();
arr[7] = (byte)((m1 << 4) | (arr[7] & 0xF));
arr[8] = (byte)((m2 << 4) | (arr[8] & 0xF));
return new Guid(arr);
}
static int ExtractMachine(Guid guid)
{
var arr = guid.ToByteArray();
return
((arr[7] >> 4) & 0xF) |
(((arr[8] >> 4) & 0xF) << 4);
}
pomocą wersji i „y” (Redux)
można nadal utrzymywać wartość „y”, ograniczając ilość urządzeń do 63 (przy użyciu 2 ostatnie bity do reprezentowania 4 możliwe wartości 'Y'):
static Guid NewSystemGuid(int machine)
{
if (machine < 0 | machine > 0x3F)
throw new ArgumentOutOfRangeException("machine");
var m1 = machine & 0xF;
var m2 = (machine >> 4) & 0xF;
var g = Guid.NewGuid();
var arr = g.ToByteArray();
arr[7] = (byte)((m1 << 4) | (arr[7] & 0xF));
var y = (arr[8] >> 4) & 0xF;
switch (y)
{
case 0x8:
arr[8] = (byte)((m2 << 4) | (arr[8] & 0xF));
break;
case 0x9:
arr[8] = (byte)(((m2 | 0x8) << 4) | (arr[8] & 0xF));
break;
case 0xA:
arr[8] = (byte)(((m2 | 0x4) << 4) | (arr[8] & 0xF));
break;
case 0xB:
arr[8] = (byte)(((m2 | 0xC) << 4) | (arr[8] & 0xF));
break;
default:
throw new Exception();
}
return new Guid(arr);
}
static int ExtractMachine(Guid guid)
{
var arr = guid.ToByteArray();
return
((arr[7] >> 4) & 0xF) |
(((arr[8] >> 4) & 0x3) << 4);
}
użyć wersji 1 GUID
Mogłabyś al więc używać wersji 1 GUID, jak to jeszcze możliwe ich generowania:
class SequentialGuid
{
[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);
public static Guid NewGuid()
{
Guid guid;
UuidCreateSequential(out guid);
return guid;
}
public static byte[] ExtractMacAddress(Guid guid)
{
var arr = guid.ToByteArray();
// Require version 1.
if (((arr[7] >> 4) & 0xF) != 1)
throw new ArgumentOutOfRangeException("guid", "GUID is required to be a sequential (version 1) GUID.");
var macLong = BitConverter.ToInt64(arr, arr.Length - 8);
macLong = IPAddress.NetworkToHostOrder(macLong);
arr = BitConverter.GetBytes(macLong);
Array.Resize(ref arr, 6);
return arr;
}
}
Tak - wszystkie informacje, co musisz zrobić, to w tym artykule i połączonego projektu internetowego. Zakłada się, że identyfikator GUID został wygenerowany za pomocą tego algorytmu, jeśli został wygenerowany przy użyciu innego algorytmu, musisz znaleźć specyfikację/szczegóły tego algorytmu. Możesz użyć pola Wariant (opisanego w powiązanej notatce), aby określić, który wariant układu został użyty. – Justin