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);
+ }
+ }
+ }
+}