Jelajahi Sumber

qdr.fnd.core:

- add interface Value/Generators/IIdGenerator to generate unique id
- add class Value/Generators/TinyHash to generate string-like balanced (timebased) unique id defined by length and charset
- update dependencies packages (System.IO.Abstractions)
- add Tests of TinyHash

qdr.fnd.core.avalonia:
- update dependencies packages (qdr.fnd.core)
Dalibor Votruba 2 tahun lalu
induk
melakukan
13cc52feb1

+ 8 - 7
qdr.fnd.core.avalonia/qdr.fnd.core.avalonia.csproj

@@ -16,12 +16,13 @@
     <Copyright>Copyright © 2023 Quadarax</Copyright>
     <PackageIcon>quadarax_dll.png</PackageIcon>
     <PackageTags>QDR;FND;CORE;AVALONIA</PackageTags>
-    <AssemblyVersion>0.0.1.0</AssemblyVersion>
-    <FileVersion>0.0.1.0</FileVersion>
-    <Version>0.0.1.0-alpha</Version>
-    <PackageReleaseNotes>Date:28.10.2023
-      - initial version
-	  - add Controls/StickyLabel</PackageReleaseNotes>
+    <AssemblyVersion>0.0.2.0</AssemblyVersion>
+    <FileVersion>0.0.2.0</FileVersion>
+    <Version>0.0.2.0-alpha</Version>
+    <PackageReleaseNotes>
+      Date:30.11.2023
+      - update dependencies packages (qdr.fnd.core)
+    </PackageReleaseNotes>
     <PackageReadmeFile>releasenotes.md</PackageReadmeFile>
     <Nullable>enable</Nullable>
   </PropertyGroup>
@@ -38,7 +39,7 @@
     <PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.5" />
     <PackageReference Include="Avalonia.ReactiveUI" Version="11.0.5" />
     <PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.5" />
-    <PackageReference Include="qdr.fnd.core" Version="0.0.2-alpha" />
+    <PackageReference Include="qdr.fnd.core" Version="0.0.3-alpha" />
   </ItemGroup>
 
   <ItemGroup>

+ 4 - 0
qdr.fnd.core.avalonia/releasenotes.md

@@ -1,6 +1,10 @@
 # Quadarax.Foundation.Core.Avalonia * Release notes
 Ordered by version descending
 
+## 0.0.2.0
+Date:__30.11.2023__
+- update dependencies packages (qdr.fnd.core)
+---
 ## 0.0.1.0
 Date:__28.10.2023__
 - initial version

+ 90 - 0
qdr.fnd.core.test/Value/Generators/TinyHashTest.cs

@@ -0,0 +1,90 @@
+using Quadarax.Foundation.Core.Value.Generators;
+
+namespace qdr.fnd.core.test.Value.Generators
+{
+    public class TinyHashTest
+    {
+        [Test(TestOf = typeof(TinyHash))]
+        public void ImplementsInterface()
+        {
+            Assert.IsInstanceOf<IIdGenerator<string>>(new TinyHash());
+        }
+
+        [Test(TestOf = typeof(TinyHash))]
+        public void ConstructorFail()
+        {
+            // ReSharper disable once ObjectCreationAsStatement
+            Assert.Throws<ArgumentNullException>(() => new TinyHash(null!, 5));
+            // ReSharper disable once ObjectCreationAsStatement
+            Assert.Throws<ArgumentNullException>(() => new TinyHash(string.Empty, 5));
+            // ReSharper disable once ObjectCreationAsStatement
+            Assert.Throws<ArgumentOutOfRangeException>(() => new TinyHash("A", 0));
+            // ReSharper disable once ObjectCreationAsStatement
+            Assert.Throws<ArgumentOutOfRangeException>(() => new TinyHash("A", -1));
+            // ReSharper disable once ObjectCreationAsStatement
+            Assert.Throws<ArgumentOutOfRangeException>(() => new TinyHash( 0));
+            // ReSharper disable once ObjectCreationAsStatement
+            Assert.Throws<ArgumentOutOfRangeException>(() => new TinyHash(-1));
+        }
+
+        [Test(TestOf = typeof(TinyHash))]
+        public void GenerateNumberDefault()
+        {
+            var generator = new TinyHash();
+            var result1 = generator.NewId();
+            var result2 = generator.NewId();
+
+            Assert.IsNotNull(result1);
+            Assert.IsNotNull(result2);
+            Assert.That(result2, Is.Not.EqualTo(result1));
+            Assert.That(result1.Length, Is.EqualTo(TinyHash.DefaultLength));
+            Assert.That(result2.Length, Is.EqualTo(TinyHash.DefaultLength));
+            Assert.That(ValueAmongChars(result1, TinyHash.DefaultCharset), "value has some chars out of defined charset.");
+            Assert.That(ValueAmongChars(result2, TinyHash.DefaultCharset), "value has some chars out of defined charset.");
+        }
+
+        [Test(TestOf = typeof(TinyHash))]
+        public void GenerateNumberSpecificLength()
+        {
+            var length = 3;
+            var generator = new TinyHash(length);
+            var result1 = generator.NewId();
+            var result2 = generator.NewId();
+
+            Assert.IsNotNull(result1);
+            Assert.IsNotNull(result2);
+            Assert.That(result2, Is.Not.EqualTo(result1));
+            Assert.That(result1.Length, Is.EqualTo(length));
+            Assert.That(result2.Length, Is.EqualTo(length));
+            Assert.That(ValueAmongChars(result1, TinyHash.DefaultCharset), "value has some chars out of defined charset.");
+            Assert.That(ValueAmongChars(result2, TinyHash.DefaultCharset), "value has some chars out of defined charset.");
+        }
+        [Test(TestOf = typeof(TinyHash))]
+        public void GenerateNumberCustomCharset()
+        {
+            var charset = "xyz";
+            var generator = new TinyHash(charset, TinyHash.DefaultLength);
+            var result1 = generator.NewId();
+            var result2 = generator.NewId();
+
+            Assert.IsNotNull(result1);
+            Assert.IsNotNull(result2);
+            Assert.That(result2, Is.Not.EqualTo(result1));
+            Assert.That(result1.Length, Is.EqualTo(TinyHash.DefaultLength));
+            Assert.That(result2.Length, Is.EqualTo(TinyHash.DefaultLength));
+            Assert.That(ValueAmongChars(result1,charset), "value has some chars out of defined charset.");
+            Assert.That(ValueAmongChars(result2, charset), "value has some chars out of defined charset.");
+        }
+
+        #region *** Private methods ***
+        private bool ValueAmongChars(string value, string charset)
+        {
+            foreach (var c in value)
+            {
+                if (!charset.Contains(c)) return false;
+            }
+            return true;
+        }
+        #endregion
+    }
+}

+ 0 - 4
qdr.fnd.core.test/qdr.fnd.core.test.csproj

@@ -21,8 +21,4 @@
     <ProjectReference Include="..\qdr.fnd.core\qdr.fnd.core.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="Value\" />
-  </ItemGroup>
-
 </Project>

+ 7 - 0
qdr.fnd.core/Value/Generators/IIdGenerator.cs

@@ -0,0 +1,7 @@
+namespace Quadarax.Foundation.Core.Value.Generators
+{
+    public interface IIdGenerator<TValue>
+    {
+        TValue NewId();
+    }
+}

+ 70 - 0
qdr.fnd.core/Value/Generators/TinyHash.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Security.Cryptography;
+
+
+namespace Quadarax.Foundation.Core.Value.Generators
+{
+   
+    public class TinyHash : IIdGenerator<string>
+    {
+        #region *** Constants ***
+        public const string DefaultCharset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        public const int DefaultLength = 5;
+        #endregion
+
+        #region *** Private fields ***
+        private readonly int _length;
+        private readonly string _charset;
+        #endregion
+
+        #region *** Constructors ***
+        public TinyHash(string charset, int length)
+        {
+            if (string.IsNullOrEmpty(charset)) throw new ArgumentNullException(nameof(charset));
+            if (length < 1) throw new ArgumentOutOfRangeException(nameof(length));
+
+            _charset = charset;
+            _length = length;
+        }
+
+        public TinyHash(int length) : this(DefaultCharset, length)
+        {
+        }
+
+        public TinyHash() : this(DefaultCharset, DefaultLength)
+        {
+        }
+        #endregion
+
+
+        #region *** Public Operations ***
+        public string NewId()
+        {
+            var outputChars = new char[_length];
+    
+            using var rnd = RandomNumberGenerator.Create();
+            var diff = _charset.Length;
+            var upperBound = uint.MaxValue / diff * diff;
+            var randomBuffer = new byte[sizeof(int)];
+
+            for (var i = 0; i < outputChars.Length; i++)
+            {
+                // Generate a fair, random number between minIndex and maxIndex
+                uint randomUInt;
+                do
+                {
+                    rnd.GetBytes(randomBuffer);
+                    randomUInt = BitConverter.ToUInt32(randomBuffer, 0);
+                }
+                while (randomUInt >= upperBound);
+                var charIndex = (int)(randomUInt % diff);
+
+                // Set output character based on random index
+                outputChars[i] = _charset[charIndex];
+            }
+
+            return new string(outputChars);
+        }
+        #endregion
+    }
+}

+ 9 - 18
qdr.fnd.core/qdr.fnd.core.csproj

@@ -15,23 +15,14 @@
     <Copyright>Copyright © 2023 Quadarax</Copyright>
     <PackageIcon>quadarax_dll.png</PackageIcon>
     <PackageTags>QDR;FND;CORE</PackageTags>
-    <AssemblyVersion>0.0.2.0</AssemblyVersion>
-    <FileVersion>0.0.2.0</FileVersion>
-    <Version>0.0.2.0-alpha</Version>
-    <PackageReleaseNotes>Date:27.9.2023
-      - extends Thread/LoopWorker to support external ansync iteration body expression
-      - fix Thread/ContiguousWorker to support external ansync iteration body expression
-      - add Thread/BasicWorkerContext and extends IWorkerContext to stores CancellationToken
-      - extends Thread/AbstractWorker to work with default IWorkerContext, make public AbstractWorker.Context
-      - add Json/Extensions/JsonDocumentExt.Diff function to compare two JsonDocument
-      - extends Logging/ConsoleLogger to support exclude filter in initialization
-      - add Collections/LockedList to support thread safe listng
-      - extends Thread/LoopWorker to support custom overlaping iterations
-      - add Value/StringPatternComparer to equals string and simple pattern expression
-      - add Value/Extensions/EnumerableExt.WhereEquals to use where equals with comparer provided
-      - add Value/Extensions/StringExt.Like to use string pattern comparer
-      - fix quality CA
-      - minor fixes</PackageReleaseNotes>
+    <AssemblyVersion>0.0.3.0</AssemblyVersion>
+    <FileVersion>0.0.3.0</FileVersion>
+    <Version>0.0.3.0-alpha</Version>
+    <PackageReleaseNotes>Date:30.11.2023
+      - add interface Value/Generators/IIdGenerator to generate unique id
+      - add class Value/Generators/TinyHash to generate string-like balanced (timebased) unique id defined by length and charset
+      - update dependencies packages (System.IO.Abstractions)
+    </PackageReleaseNotes>
     <PackageReadmeFile>releasenotes.md</PackageReadmeFile>
     <Nullable>enable</Nullable>
 
@@ -56,7 +47,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.IO.Abstractions" Version="19.2.69" />
+    <PackageReference Include="System.IO.Abstractions" Version="19.2.87" />
   </ItemGroup>
 
   <ItemGroup>

+ 6 - 0
qdr.fnd.core/releasenotes.md

@@ -1,6 +1,12 @@
 # Quadarax.Foundation.Core * Release notes
 Ordered by version descending
 
+## 0.0.3.0
+Date:__30.11.2023__
+- add interface Value/Generators/IIdGenerator to generate unique id
+- add class Value/Generators/TinyHash to generate string-like balanced (timebased) unique id defined by length and charset
+- update dependencies packages (System.IO.Abstractions)
+---
 ## 0.0.2.0
 Date:__19.10.2023__
 - extends Thread/LoopWorker to support external ansync iteration body expression