Skip to content

Commit

Permalink
Create UUIDv4.cs
Browse files Browse the repository at this point in the history
Class Library to generate Universally Unique Identifier (UUID) / Globally Unique Identifier (GUID) based on Version 4 (random).
Relying on System.Security.Cryptography.RNGCryptoServiceProvider to provide the random bytes.
  • Loading branch information
amsga committed Sep 10, 2021
1 parent 887bd09 commit aacfca3
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 10 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
20 changes: 10 additions & 10 deletions UUIDUtil/UUIDUtil.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>TensionDev.UUID</AssemblyName>
<RootNamespace>TensionDev.UUID</RootNamespace>
<PackageId>TensionDev.UUID</PackageId>
<Product>TensionDev.UUID</Product>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<Company>TensionDev</Company>
<PackageId>TensionDev.UUID</PackageId>
<Version>0.2.0</Version>
<Authors>TensionDev amsga</Authors>
<NeutralLanguage>en-SG</NeutralLanguage>
<Company>TensionDev</Company>
<Product>TensionDev.UUID</Product>
<Description>A project to store various UUID functions within a library for future use.</Description>
<Copyright>Copyright (c) TensionDev 2021</Copyright>
<PackageTags>UUID GUID</PackageTags>
<PackageReleaseNotes>Initial Release with UUID / GUID Version 1</PackageReleaseNotes>
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/TensionDev/UUIDUtil</PackageProjectUrl>
<RepositoryUrl>https://github.com/TensionDev/UUIDUtil</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>0.1.1</Version>
<AssemblyVersion>0.1.0.0</AssemblyVersion>
<FileVersion>0.1.1.0</FileVersion>
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<PackageTags>UUID GUID</PackageTags>
<PackageReleaseNotes>Release with UUID / GUID Version 1 and Version 4.</PackageReleaseNotes>
<NeutralLanguage>en-SG</NeutralLanguage>
<AssemblyVersion>0.2.0.0</AssemblyVersion>
<FileVersion>0.2.0.0</FileVersion>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
Expand Down
55 changes: 55 additions & 0 deletions UUIDUtil/UUIDv4.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;

namespace TensionDev.UUID
{
/// <summary>
/// Class Library to generate Universally Unique Identifier (UUID) / Globally Unique Identifier (GUID) based on Version 4 (random).
/// </summary>
public class UUIDv4
{
/// <summary>
/// Initialises a new GUID/UUID based on Version 4 (random)
/// </summary>
/// <returns>A new Guid object</returns>
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;
}
}
}
49 changes: 49 additions & 0 deletions XUnitTestProjectUUID/UnitTestUUIDv4.cs
Original file line number Diff line number Diff line change
@@ -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<String> concurrentBag = new ConcurrentBag<String>();

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<char> expectedVariantField = new List<char>() { '8', '9', 'a', 'b' };

ConcurrentBag<String> concurrentBag = new ConcurrentBag<String>();

Parallel.For(0, UInt16.MaxValue,
body =>
{
concurrentBag.Add(TensionDev.UUID.UUIDv4.NewUUIDv4().ToString());
});

foreach (String value in concurrentBag)
{
Assert.Contains<char>(value[19], expectedVariantField);
}
}
}
}

0 comments on commit aacfca3

Please sign in to comment.