Example #1
0
        /// <summary>
        /// Generate a namespace GUID (V3 or V5) with a given algorithm
        /// </summary>
        /// <param name="namespaceId">The namespace we're generating the GUID in</param>
        /// <param name="name">The name we're generating the GUID for</param>
        /// <param name="version">The version to generate (MD5 or SHA1)</param>
        /// <returns></returns>
        private static UUID GenerateNameBased(System.Guid namespaceId, string name, GuidVersion version)
        {
            if (version != GuidVersion.MD5 && version != GuidVersion.SHA1)
            {
                throw new ArgumentException("version", "Name based guids can only be version 3, or 5");
            }

            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name", "The name parameter cannot be empty or null");
            }

            byte[] nameBytes      = Encoding.UTF8.GetBytes(name);
            byte[] namespaceBytes = namespaceId.ToByteArray();

            if (BitConverter.IsLittleEndian)
            {
                ToggleEndianess(namespaceBytes);
            }

            var hash = version == GuidVersion.MD5 ?
                       HashProvider.GenerateMD5Hash(namespaceBytes, nameBytes) :
                       HashProvider.GenerateSHA1Hash(namespaceBytes, nameBytes);

            if (BitConverter.IsLittleEndian)
            {
                ToggleEndianess(hash);
            }

            return(GenerateFromComponents(
                       hash.Skip(Constants.TIMESTAMP_BYTE_INDEX).Take(Constants.TIME_BYTES_LENGTH).ToArray(),
                       hash.Skip(Constants.CLOCK_SEQUENCE_BYTE_INDEX).Take(Constants.CLOCK_SEQUENCE_BYTES_LENGTH).ToArray(),
                       hash.Skip(Constants.NODE_BYTE_INDEX).Take(Constants.NODE_BYTES_LENGTH).ToArray(),
                       version, GuidVariant.RFC4122));
        }
Example #2
0
        public static Guid Create(Guid @namespace, byte[] name, GuidVersion version)
        {
            var namespaceBytes = @namespace.ToBigEndianByteArray();

            byte[] hash;
            using (var algorithm = version == GuidVersion.NameBasedMd5 ? MD5.Create() : SHA1.Create() as HashAlgorithm)
            {
                algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0);
                algorithm.TransformFinalBlock(name, 0, name.Length);
                hash = algorithm.Hash;
            }

            var guidBytes = new byte[16];

            Array.Copy(hash, 0, guidBytes, 0, 16);
            GuidUtility.EndianSwap(guidBytes);

            //Variant RFC4122
            guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80);//big-endian octet 8

            //Version
            guidBytes[7] = (byte)((guidBytes[7] & 0x0F) | ((int)version << 4));//big-endian octet 6

            return(new Guid(guidBytes));
        }
Example #3
0
        /// <summary>
        /// Creates a named, MD5-based (version 3) GUID.
        /// </summary>
        /// <param name="namespace">The GUID that defines the namespace.</param>
        /// <param name="name">The name within that namespace.</param>
        /// <param name="version">The version of GUID to create.</param>
        private static Guid CreateNamed(Guid @namespace, byte[] name, GuidVersion version)
        {
            var namespaceBytes = @namespace.ToBigEndianByteArray();

            byte[] hash;
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
#pragma warning disable CA5350 // Do Not Use Weak Cryptographic Algorithms
            using (var algorithm = version == GuidVersion.NameBasedMd5 ? MD5.Create() : SHA1.Create() as HashAlgorithm)
#pragma warning restore CA5350 // Do Not Use Weak Cryptographic Algorithms
#pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms
            {
                algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0);
                algorithm.TransformFinalBlock(name, 0, name.Length);
                hash = algorithm.Hash;
            }

            var guidBytes = new byte[16];
            Array.Copy(hash, 0, guidBytes, 0, 16);
            GuidUtility.EndianSwap(guidBytes);

            // Variant RFC4122
            guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80); // big-endian octet 8

            // Version
            guidBytes[7] = (byte)((guidBytes[7] & 0x0F) | ((int)version << 4)); // big-endian octet 6

            return(new Guid(guidBytes));
        }
Example #4
0
        /// <summary>
        /// Create
        /// </summary>
        /// <param name="namespace"></param>
        /// <param name="name"></param>
        /// <param name="version"></param>
        /// <returns></returns>
        public static Guid Create(Guid @namespace, byte[] name, GuidVersion version)
        {
            switch (version)
            {
            //Creates a random (version 4) GUID.
            case GuidVersion.Random:
                return(CreateRandom());

            //Creates a named, MD5-based (version 3) GUID.
            case GuidVersion.NameBasedMd5:
                return(NamedGuidProvider.Create(@namespace, name, GuidVersion.NameBasedMd5));

            //Creates a named, SHA1-based (version 5) GUID.
            case GuidVersion.NameBasedSha1:
                return(NamedGuidProvider.Create(@namespace, name, GuidVersion.NameBasedSha1));

            case GuidVersion.TimeBased:
                return(Create(CombStyle.NormalStyle));

            //Creates a random (version 4) GUID.
            default:
                return(Guid.NewGuid());
            }
        }
Example #5
0
        /// <summary>
        /// Generate a GUID from its components
        /// </summary>
        /// <param name="timeBytes">The time based component</param>
        /// <param name="clockSequenceBytes">The clock sequence component</param>
        /// <param name="nodeBytes">The node component</param>
        /// <param name="version">The GUID version</param>
        /// <param name="variant">The GUID variant</param>
        /// <returns></returns>
        private static UUID GenerateFromComponents(byte[] timeBytes, byte[] clockSequenceBytes, byte[] nodeBytes, GuidVersion version, GuidVariant variant)
        {
            var guidBytes = new byte[Constants.GUID_BYTES_LENGTH];

            if (clockSequenceBytes == null)
            {
                throw new ArgumentException("Please specify the clock sequence bytes", "clockSequenceBytes");
            }

            if (nodeBytes == null)
            {
                throw new ArgumentException("Please specify the node bytes", "nodeBytes");
            }

            if (clockSequenceBytes.Length != Constants.CLOCK_SEQUENCE_BYTES_LENGTH)
            {
                throw new ArgumentException("The clock sequence bytes must be of length " + Constants.CLOCK_SEQUENCE_BYTES_LENGTH, "clockSequenceBytes");
            }

            if (nodeBytes.Length != Constants.NODE_BYTES_LENGTH)
            {
                throw new ArgumentException("The node bytes must be of length " + Constants.NODE_BYTES_LENGTH, "nodeBytes");
            }

            if (timeBytes.Length != Constants.TIME_BYTES_LENGTH)
            {
                throw new ArgumentException("The time bytes must be of length " + Constants.TIME_BYTES_LENGTH, "nodeBytes");
            }

            //Copy over the different byte segments
            Array.Copy(timeBytes, 0, guidBytes, Constants.TIMESTAMP_BYTE_INDEX, Constants.TIME_BYTES_LENGTH);
            Array.Copy(clockSequenceBytes, 0, guidBytes, Constants.CLOCK_SEQUENCE_BYTE_INDEX, Constants.CLOCK_SEQUENCE_BYTES_LENGTH);
            Array.Copy(nodeBytes, 0, guidBytes, Constants.NODE_BYTE_INDEX, Constants.NODE_BYTES_LENGTH);

            //To put in the variant, take the  9th byte and perform an and operation using  0x3f, followed by an or operation with 0x80.

            //Put in the version
            int maskVariant  = 0x3f;
            int shiftVariant = 0;

            switch (variant)
            {
            case GuidVariant.FutureReserved:
                maskVariant  = 0x1F;
                shiftVariant = 0xE0;
                break;

            case GuidVariant.MicrosoftReserved:
                maskVariant  = 0x1F;
                shiftVariant = 0xC0;
                break;

            case GuidVariant.NCSReserved:
                maskVariant  = 0x0;
                shiftVariant = 0x0;
                break;

            case GuidVariant.RFC4122:
                maskVariant  = 0x3f;
                shiftVariant = 0x80;
                break;

            default:
                maskVariant  = 0x3f;
                shiftVariant = 0;
                break;
            }

            int maskVersion  = 0x3f;
            int shiftVersion = 0x3f;

            switch (version)
            {
            case GuidVersion.DCE:
                maskVersion  = 0x0f;
                shiftVersion = 0x20;
                break;

            case GuidVersion.MD5:
                maskVersion  = 0x0f;
                shiftVersion = 0x30;
                break;

            case GuidVersion.Random:
                maskVersion  = 0x0f;
                shiftVersion = 0x40;
                break;

            case GuidVersion.SHA1:
                maskVersion  = 0x0f;
                shiftVersion = 0x50;
                break;

            case GuidVersion.Time:
                maskVersion  = 0x0f;
                shiftVersion = 0x10;
                break;

            default:
                maskVersion  = 0x3f;
                shiftVersion = 0;
                break;
            }

            guidBytes[Constants.VARIANT_BYTE_INDEX] &= (byte)maskVariant;
            guidBytes[Constants.VARIANT_BYTE_INDEX] |= (byte)shiftVariant;

            guidBytes[Constants.VERSION_BYTE_INDEX] &= (byte)maskVersion;
            guidBytes[Constants.VERSION_BYTE_INDEX] |= (byte)shiftVersion;

            return(new UUID(new System.Guid(guidBytes)));
        }
 public GuidAttribute(GuidVersion version = (GuidVersion) ~0)
 {
     this.version = version;
 }