|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
This article has been provided courtesy of MSDN. SummaryThe ContentsOverviewThe .NET Compact Framework team constantly made tradeoffs between the framework footprint size, performance, and implementation time. The full .NET Framework It turns out that it's easy to write a custom implementation of the
Figure 1. Generating GUIDs on the Pocket PC The GUID FormatGUIDs consist of random numbers grouped into several sections: timestamp, clock sequence and node. The different sections for the Table 1. Different sections of a GUID.
VariantOne to three bits of the clock sequence section are used to define the variant, or layout, of the GUID. Windows and the Table 2. Variant information stored in GUIDs
VersionThe upper four bits of the timestamp section contain the GUID's version that specifies the content of each section. Before Windows 2000, the Table 3. Version information stored in GUIDs
The following sites contain more information on the GUID specification:
Generating Random NumbersThe The
The PocketGuid ClassNow that we know the GUID format (128 bit random number with multiplexed variant and version bits), and how to generate random numbers (use crypto API functions), it's very easy to implement the The class contains two private enums,
C#using System;
using System.Runtime.InteropServices;
namespace PocketGuid
{
/// <summary>
/// Generate GUIDs on the .NET Compact Framework.
/// </summary>
public class PocketGuid
{
// guid variant types
private enum GuidVariant
{
ReservedNCS = 0x00,
Standard = 0x02,
ReservedMicrosoft = 0x06,
ReservedFuture = 0x07
}
// guid version types
private enum GuidVersion
{
TimeBased = 0x01,
Reserved = 0x02,
NameBased = 0x03,
Random = 0x04
}
// constants that are used in the class
private class Const
{
// number of bytes in guid
public const int ByteArraySize = 16;
// multiplex variant info
public const int VariantByte = 8;
public const int VariantByteMask = 0x3f;
public const int VariantByteShift = 6;
// multiplex version info
public const int VersionByte = 7;
public const int VersionByteMask = 0x0f;
public const int VersionByteShift = 4;
}
// imports for the crypto api functions
private class WinApi
{
public const uint PROV_RSA_FULL = 1;
public const uint CRYPT_VERIFYCONTEXT = 0xf0000000;
[DllImport("coredll.dll")]
public static extern bool CryptAcquireContext(
ref IntPtr phProv, string pszContainer, string pszProvider,
uint dwProvType, uint dwFlags);
[DllImport("coredll.dll")]
public static extern bool CryptReleaseContext(
IntPtr hProv, uint dwFlags);
[DllImport("coredll.dll")]
public static extern bool CryptGenRandom(
IntPtr hProv, int dwLen, byte[] pbBuffer);
}
// all static methods
private PocketGuid()
{
}
/// <summary>
/// Return a new System.Guid object.
/// </summary>
public static Guid NewGuid()
{
IntPtr hCryptProv = IntPtr.Zero;
Guid guid = Guid.Empty;
try
{
// holds random bits for guid
byte[] bits = new byte[Const.ByteArraySize];
// get crypto provider handle
if (!WinApi.CryptAcquireContext(ref hCryptProv, null, null,
WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT))
{
throw new SystemException(
"Failed to acquire cryptography handle.");
}
// generate a 128 bit (16 byte) cryptographically random number
if (!WinApi.CryptGenRandom(hCryptProv, bits.Length, bits))
{
throw new SystemException(
"Failed to generate cryptography random bytes.");
}
// set the variant
bits[Const.VariantByte] &= Const.VariantByteMask;
bits[Const.VariantByte] |=
((int)GuidVariant.Standard << Const.VariantByteShift);
// set the version
bits[Const.VersionByte] &= Const.VersionByteMask;
bits[Const.VersionByte] |=
((int)GuidVersion.Random << Const.VersionByteShift);
// create the new System.Guid object
guid = new Guid(bits);
}
finally
{
// release the crypto provider handle
if (hCryptProv != IntPtr.Zero)
WinApi.CryptReleaseContext(hCryptProv, 0);
}
return guid;
}
}
}
VB.NETImports System.Runtime.InteropServices
'
' Generate GUIDs on the .NET Compact Framework.
'
Public Class PocketGuid
' guid variant types
Private Enum GuidVariant
ReservedNCS = &H0
Standard = &H2
ReservedMicrosoft = &H6
ReservedFuture = &H7
End Enum
' guid version types
Private Enum GuidVersion
TimeBased = &H1
Reserved = &H2
NameBased = &H3
Random = &H4
End Enum
' constants that are used in the class
Private Class ConstValues
' number of bytes in guid
Public Const ByteArraySize As Integer = 16
' multiplex variant info
Public Const VariantByte As Integer = 8
Public Const VariantByteMask As Integer = &H3F
Public Const VariantByteShift As Integer = 6
' multiplex version info
Public Const VersionByte As Integer = 7
Public Const VersionByteMask As Integer = &HF
Public Const VersionByteShift As Integer = 4
End Class
' imports for the crypto api functions
Private Class WinApi
Public Const PROV_RSA_FULL As Integer = 1
Public Const CRYPT_VERIFYCONTEXT As Integer = &HF0000000
<DllImport("coredll.dll")> _
Public Shared Function CryptAcquireContext( _
ByRef phProv As IntPtr, ByVal pszContainer As String, _
ByVal pszProvider As String, ByVal dwProvType As Integer, _
ByVal dwFlags As Integer) As Boolean
End Function
<DllImport("coredll.dll")> _
Public Shared Function CryptReleaseContext( _
ByVal hProv As IntPtr, ByVal dwFlags As Integer) As Boolean
End Function
<DllImport("coredll.dll")> _
Public Shared Function CryptGenRandom( _
ByVal hProv As IntPtr, ByVal dwLen As Integer, _
ByVal pbBuffer() As Byte) As Boolean
End Function
End Class
' all static methods
Private Sub New()
End Sub
' Return a new System.Guid object.
Public Shared Function NewGuid() As Guid
Dim hCryptProv As IntPtr = IntPtr.Zero
Dim guid As Guid = guid.Empty
Try
' holds random bits for guid
Dim bits(ConstValues.ByteArraySize - 1) As Byte
' get crypto provider handle
If Not WinApi.CryptAcquireContext(hCryptProv, Nothing, Nothing, _
WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT) Then
Throw New SystemException( _
"Failed to acquire cryptography handle.")
End If
' generate a 128 bit (16 byte) cryptographically random number
If Not WinApi.CryptGenRandom(hCryptProv, bits.Length, bits) Then
Throw New SystemException( _
"Failed to generate cryptography random bytes.")
End If
' set the variant
bits(ConstValues.VariantByte) = bits(ConstValues.VariantByte) And _
CByte(ConstValues.VariantByteMask)
bits(ConstValues.VariantByte) = bits(ConstValues.VariantByte) Or _
CByte(GuidVariant.Standard << ConstValues.VariantByteShift)
' set the version
bits(ConstValues.VersionByte) = bits(ConstValues.VersionByte) And _
CByte(ConstValues.VersionByteMask)
bits(ConstValues.VersionByte) = bits(ConstValues.VersionByte) Or _
CByte(GuidVersion.Random << ConstValues.VersionByteShift)
' create the new System.Guid object
guid = New Guid(bits)
Finally
' release the crypto provider handle
If Not hCryptProv.Equals(IntPtr.Zero) Then
WinApi.CryptReleaseContext(hCryptProv, 0)
End If
End Try
Return guid
End Function
End Class
GUID TriviaHere are some GUID trivia questions you can use to impress your co-workers. You can run the PocketGuid test application or guidgen.exe on your desktop to check the questions; however, checking the last question might take a while.
Links
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||