diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d6ca2a..2312ff5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [v0.2.0] - 2021-09-10 +[v0.2.0](https://github.com/TensionDev/UUIDUtil/releases/tag/v0.2.0) + +### Added +- Added UUID v4 generated based on Pseudo Random Number Generator, System.Security.Cryptography.RNGCryptoServiceProvider. + + ## [v0.1.1] - 2021-09-10 [v0.1.1](https://github.com/TensionDev/UUIDUtil/releases/tag/v0.1.1) diff --git a/UUIDUtil/UUIDUtil.csproj b/UUIDUtil/UUIDUtil.csproj index 7263cbc..dac664f 100644 --- a/UUIDUtil/UUIDUtil.csproj +++ b/UUIDUtil/UUIDUtil.csproj @@ -4,24 +4,24 @@ netstandard2.0 TensionDev.UUID TensionDev.UUID - TensionDev.UUID - TensionDev.UUID true true - TensionDev + TensionDev.UUID + 0.2.0 TensionDev amsga - en-SG + TensionDev + TensionDev.UUID A project to store various UUID functions within a library for future use. Copyright (c) TensionDev 2021 - UUID GUID - Initial Release with UUID / GUID Version 1 + GPL-3.0-or-later https://github.com/TensionDev/UUIDUtil https://github.com/TensionDev/UUIDUtil git - 0.1.1 - 0.1.0.0 - 0.1.1.0 - GPL-3.0-or-later + UUID GUID + Release with UUID / GUID Version 1 and Version 4. + en-SG + 0.2.0.0 + 0.2.0.0 true snupkg diff --git a/UUIDUtil/UUIDv4.cs b/UUIDUtil/UUIDv4.cs new file mode 100644 index 0000000..c9b39b7 --- /dev/null +++ b/UUIDUtil/UUIDv4.cs @@ -0,0 +1,55 @@ +using System; + +namespace TensionDev.UUID +{ + /// + /// Class Library to generate Universally Unique Identifier (UUID) / Globally Unique Identifier (GUID) based on Version 4 (random). + /// + public class UUIDv4 + { + /// + /// Initialises a new GUID/UUID based on Version 4 (random) + /// + /// A new Guid object + public static Guid NewUUIDv4() + { + Byte[] time = new Byte[8]; + Byte[] clockSequence = new Byte[2]; + Byte[] nodeID = new Byte[6]; + + using (System.Security.Cryptography.RNGCryptoServiceProvider cryptoServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider()) + { + cryptoServiceProvider.GetBytes(time); + cryptoServiceProvider.GetBytes(clockSequence); + cryptoServiceProvider.GetBytes(nodeID); + } + + Byte[] hex = new Byte[16]; + + hex[0] = time[0]; + hex[1] = time[1]; + hex[2] = time[2]; + hex[3] = time[3]; + + hex[4] = time[4]; + hex[5] = time[5]; + + hex[6] = time[6]; + hex[7] = (Byte)((time[7] & 0x0F) + 0x40); + + hex[8] = (Byte)((clockSequence[0] & 0x3F) + 0x80); + hex[9] = clockSequence[1]; + + hex[10] = nodeID[0]; + hex[11] = nodeID[1]; + hex[12] = nodeID[2]; + hex[13] = nodeID[3]; + hex[14] = nodeID[4]; + hex[15] = nodeID[5]; + + Guid Id = new Guid(hex); + + return Id; + } + } +} diff --git a/XUnitTestProjectUUID/UnitTestUUIDv4.cs b/XUnitTestProjectUUID/UnitTestUUIDv4.cs new file mode 100644 index 0000000..8dd1cfd --- /dev/null +++ b/XUnitTestProjectUUID/UnitTestUUIDv4.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading.Tasks; +using Xunit; + +namespace XUnitTestProjectUUID +{ + public class UnitTestUUIDv4 + { + [Fact] + public void TestNewUUIDv4() + { + char expectedVersionField = '4'; + + ConcurrentBag concurrentBag = new ConcurrentBag(); + + Parallel.For(0, UInt16.MaxValue, + body => + { + concurrentBag.Add(TensionDev.UUID.UUIDv4.NewUUIDv4().ToString()); + }); + + foreach (String value in concurrentBag) + { + Assert.Equal(value[14], expectedVersionField); + } + } + + [Fact] + public void TestUUIDVariantField() + { + IList expectedVariantField = new List() { '8', '9', 'a', 'b' }; + + ConcurrentBag concurrentBag = new ConcurrentBag(); + + Parallel.For(0, UInt16.MaxValue, + body => + { + concurrentBag.Add(TensionDev.UUID.UUIDv4.NewUUIDv4().ToString()); + }); + + foreach (String value in concurrentBag) + { + Assert.Contains(value[19], expectedVariantField); + } + } + } +}