diff --git a/README.md b/README.md
index e966a30..bc00d28 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This project is a C# implementation of the Reed-Solomon error correction algorit
## Description
-Creating and maintaining projects can be challenging. This implementation simplifies integration of Reed-Solomon error correction into your applications. Originally used privately, I decided to publish this implementation under the MIT License.
+This implementation simplifies integration of Reed-Solomon error correction into your applications.
If you find this project helpful, please consider starring it and sharing it with others.
@@ -20,54 +20,178 @@ Install-Package Witteborn.ReedSolomon
Using the Reed-Solomon library is straightforward. Here's a simple example of how to encode and decode data:
-### Example: Encode and Decode
+### Managed Example: Byte
```csharp
-using Witteborn.ReedSolomon;
-using System;
-using System.Linq;
+Console.WriteLine("Managed Example Byte");
+Console.WriteLine("--------------------");
+const int dataShardCount = 4;
+const int parityShardCount = 2;
-class Program
+// Initialize Reed-Solomon with data shards and parity shards
+ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
+
+// Example data to encode
+byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+Console.WriteLine("Data:");
+Console.WriteLine(string.Join(" ", data));
+
+// Encode the data using ManagedEncode to produce shards
+var shards = rs.ManagedEncode(data, dataShardCount, parityShardCount);
+
+Console.WriteLine("Encoded Data:");
+foreach (var shard in shards)
+{
+ Console.WriteLine(string.Join(" ", shard));
+}
+
+// Simulate loss of one shard
+shards[1] = null;
+
+Console.WriteLine("Encoded with missing Data:");
+foreach (var shard in shards)
+{
+ if (shard == null)
+ {
+ Console.WriteLine("null");
+ }
+ else
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+}
+
+// Decode the remaining shards using ManagedDecode to recover original data
+var decodedData = rs.ManagedDecode(shards, dataShardCount, parityShardCount);
+
+Console.WriteLine("Decoded data:");
+Console.WriteLine(string.Join(" ", decodedData));
+```
+
+### Managed Example: SByte
+
+```csharp
+Console.WriteLine("Managed Example SByte");
+Console.WriteLine("---------------------");
+const int dataShardCount = 4;
+const int parityShardCount = 2;
+
+// Initialize Reed-Solomon with data shards and parity shards
+ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
+
+// Example data to encode
+sbyte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+Console.WriteLine("Data:");
+Console.WriteLine(string.Join(" ", data));
+
+// Encode the data using ManagedEncode to produce shards
+var shards = rs.ManagedEncode(data, dataShardCount, parityShardCount);
+
+Console.WriteLine("Encoded Data:");
+
+foreach (var shard in shards)
+{
+ Console.WriteLine(string.Join(" ", shard));
+}
+
+// Simulate loss of one shard
+shards[1] = null;
+
+Console.WriteLine("Encoded with missing Data:");
+foreach (var shard in shards)
+{
+ if (shard == null)
+ {
+ Console.WriteLine("null");
+ }
+ else
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+}
+
+// Decode the remaining shards using ManagedDecode to recover original data
+var decodedData = rs.ManagedDecode(shards, dataShardCount, parityShardCount);
+
+Console.WriteLine("Decoded data:");
+Console.WriteLine(string.Join(" ", decodedData));
+```
+
+### Manual Example: SByte
+
+```csharp
+Console.WriteLine("Example SByte");
+Console.WriteLine("-------------");
+
+const int dataShardCount = 4;
+const int parityShardCount = 2;
+const int shardSize = 4;
+
+// Create the shards array with data and empty parity shards
+sbyte[][] shards =
+{
+ new sbyte[] { 0, 1, 2, 3 },
+ new sbyte[] { 4, 5, 6, 7 },
+ new sbyte[] { 8, 9, 10, 11 },
+ new sbyte[] { 12, 13, 14, 15 },
+ new sbyte[shardSize], // Parity shard 1
+ new sbyte[shardSize] // Parity shard 2
+};
+
+Console.WriteLine("Shards:");
+foreach (var shard in shards)
+{
+ Console.WriteLine(string.Join(" ", shard));
+}
+
+// Initialize Reed-Solomon with data shards and parity shards
+ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
+
+// Encode the data with Reed-Solomon to generate parity shards
+rs.EncodeParity(shards, 0, shardSize);
+
+Console.WriteLine("Encoded data:");
+foreach (var shard in shards)
{
- static void Main()
+ Console.WriteLine(string.Join(" ", shard));
+}
+
+// Simulate loss of one shard (e.g., network transmission loss)
+shards[1] = null; // Simulating the shard is lost
+
+Console.WriteLine("Encoded with missing Data:");
+foreach (var shard in shards)
+{
+ if (shard == null)
+ {
+ Console.WriteLine("null");
+ }
+ else
+ {
+ Console.WriteLine(string.join(" ", shard));
+ }
+}
+
+bool[] shardPresent = shards.Select(shard => shard != null).ToArray();
+
+//Manual null fix
+for (int i = 0; i < shards.Length; i++)
+{
+ if (shards[i] == null)
{
- const int dataShardCount = 4;
- const int parityShardCount = 2;
- const int totalShardCount = dataShardCount + parityShardCount;
- const int shardSize = 4;
-
- // Create the shards array with data and empty parity shards
- sbyte[][] shards = new sbyte[totalShardCount][]
- {
- new sbyte[] { 0, 1, 2, 3 },
- new sbyte[] { 4, 5, 6, 7 },
- new sbyte[] { 8, 9, 10, 11 },
- new sbyte[] { 12, 13, 14, 15 },
- new sbyte[shardSize], // Parity shard 1
- new sbyte[shardSize] // Parity shard 2
- };
-
- // Initialize Reed-Solomon with data shards and parity shards
- ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
-
- // Encode the data with Reed-Solomon to generate parity shards
- rs.EncodeParity(shards, 0, shardSize);
-
- // Simulate loss of one shard (e.g., network transmission loss)
- shards[1] = null; // Simulating the shard is lost
- bool[] shardPresent = shards.Select(shard => shard != null).ToArray();
-
- // Decode the remaining shards to recover original data
- rs.DecodeMissing(shards, shardPresent, 0, shardSize);
-
- // Print the decoded data (should match original data)
- Console.WriteLine("Decoded data:");
- foreach (var shard in shards.Where(s => s != null))
- {
- Console.WriteLine(string.Join(" ", shard));
- }
+ shards[i] = new sbyte[shardSize];
}
}
+
+// Decode the remaining shards to recover original data
+rs.DecodeMissing(shards, shardPresent, 0, shardSize);
+
+// Print the decoded data (should match original data)
+Console.WriteLine("Decoded data:");
+foreach (var shard in shards.Where(s => s != null))
+{
+ Console.WriteLine(string.Join(" ", shard));
+}
```
## Contribution
@@ -86,4 +210,4 @@ To report security issues or vulnerabilities, refer to our [Security](./SECURITY
- **Backblaze** for the original Java implementation that inspired this project.
-And a big **Thank You** to all contributors, issue reporters, and supporters who have helped make this project possible.
+And a big **Thank You** to all contributors, issue reporters, and supporters who have helped make this project possible.
\ No newline at end of file
diff --git a/ReedSolomon/ReadmeExample/Program.cs b/ReedSolomon/ReadmeExample/Program.cs
new file mode 100644
index 0000000..2bb5125
--- /dev/null
+++ b/ReedSolomon/ReadmeExample/Program.cs
@@ -0,0 +1,193 @@
+using Witteborn.ReedSolomon;
+
+ManagedExample_SByte();
+
+Console.WriteLine();
+Console.WriteLine();
+
+ManagedExample_Byte();
+
+Console.WriteLine();
+Console.WriteLine();
+
+Example_SByte();
+
+
+
+
+void ManagedExample_SByte()
+{
+ Console.WriteLine("Managed Example SByte");
+ Console.WriteLine("---------------------");
+ const int dataShardCount = 4;
+ const int parityShardCount = 2;
+
+ // Initialize Reed-Solomon with data shards and parity shards
+ ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
+
+ // Example data to encode
+ sbyte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ Console.WriteLine("Data:");
+ Console.WriteLine(string.Join(" ", data));
+
+ // Encode the data using ManagedEncode to produce shards
+ var shards = rs.ManagedEncode(data, dataShardCount, parityShardCount);
+
+ Console.WriteLine("Encoded Data:");
+
+ foreach (var shard in shards)
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+
+ // Simulate loss of one shard
+ shards[1] = null;
+
+ Console.WriteLine("Encoded with missing Data:");
+ foreach (var shard in shards)
+ {
+ if (shard == null)
+ {
+ Console.WriteLine("null");
+ }
+ else
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+ }
+
+ // Decode the remaining shards using ManagedDecode to recover original data
+ var decodedData = rs.ManagedDecode(shards, dataShardCount, parityShardCount);
+
+ Console.WriteLine("Decoded data:");
+ Console.WriteLine(string.Join(" ", decodedData));
+}
+
+void Example_SByte()
+{
+ Console.WriteLine("Example SByte");
+ Console.WriteLine("-------------");
+
+
+ const int dataShardCount = 4;
+ const int parityShardCount = 2;
+ const int totalShardCount = dataShardCount + parityShardCount;
+ const int shardSize = 4;
+
+ // Create the shards array with data and empty parity shards
+ sbyte[][] shards =
+ [
+ [0, 1, 2, 3],
+ [4, 5, 6, 7],
+ [8, 9, 10, 11],
+ [12, 13, 14, 15],
+ new sbyte[shardSize], // Parity shard 1
+ new sbyte[shardSize] // Parity shard 2
+ ];
+
+ Console.WriteLine("Shards:");
+ foreach (var shard in shards)
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+
+ // Initialize Reed-Solomon with data shards and parity shards
+ ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
+
+
+
+ // Encode the data with Reed-Solomon to generate parity shards
+ rs.EncodeParity(shards, 0, shardSize);
+
+ Console.WriteLine("Encoded data:");
+
+ foreach (var shard in shards)
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+
+ // Simulate loss of one shard (e.g., network transmission loss)
+ shards[1] = null; // Simulating the shard is lost
+
+ Console.WriteLine("Encoded with missing Data:");
+ foreach (var shard in shards)
+ {
+ if (shard == null)
+ {
+ Console.WriteLine("null");
+ }
+ else
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+ }
+
+ bool[] shardPresent = shards.Select(shard => shard != null).ToArray();
+
+ //Manual null fix
+ for (int i = 0; i < shards.Length; i++)
+ {
+ if (shards[i] == null)
+ {
+ shards[i] = new sbyte[shardSize];
+ }
+ }
+
+ // Decode the remaining shards to recover original data
+ rs.DecodeMissing(shards, shardPresent, 0, shardSize);
+
+ // Print the decoded data (should match original data)
+ Console.WriteLine("Decoded data:");
+ foreach (var shard in shards.Where(s => s != null))
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+}
+
+
+void ManagedExample_Byte()
+{
+ Console.WriteLine("Managed Example Byte");
+ Console.WriteLine("--------------------");
+ const int dataShardCount = 4;
+ const int parityShardCount = 2;
+
+ // Initialize Reed-Solomon with data shards and parity shards
+ ReedSolomon rs = new ReedSolomon(dataShardCount, parityShardCount);
+
+ // Example data to encode
+ byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ Console.WriteLine("Data:");
+ Console.WriteLine(string.Join(" ", data));
+
+ // Encode the data using ManagedEncode to produce shards
+ var shards = rs.ManagedEncode(data, dataShardCount, parityShardCount);
+
+ Console.WriteLine("Encoded Data:");
+ foreach (var shard in shards)
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+
+ // Simulate loss of one shard
+ shards[1] = null;
+
+ Console.WriteLine("Encoded with missing Data:");
+ foreach (var shard in shards)
+ {
+ if (shard == null)
+ {
+ Console.WriteLine("null");
+ }
+ else
+ {
+ Console.WriteLine(string.Join(" ", shard));
+ }
+ }
+
+ // Decode the remaining shards using ManagedDecode to recover original data
+ var decodedData = rs.ManagedDecode(shards, dataShardCount, parityShardCount);
+
+ Console.WriteLine("Decoded data:");
+ Console.WriteLine(string.Join(" ", decodedData));
+}
\ No newline at end of file
diff --git a/ReedSolomon/ReadmeExample/ReadmeExample.csproj b/ReedSolomon/ReadmeExample/ReadmeExample.csproj
new file mode 100644
index 0000000..09cde25
--- /dev/null
+++ b/ReedSolomon/ReadmeExample/ReadmeExample.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/ReedSolomon/ReedSolomon.sln b/ReedSolomon/ReedSolomon.sln
index 814033b..b7c4207 100644
--- a/ReedSolomon/ReedSolomon.sln
+++ b/ReedSolomon/ReedSolomon.sln
@@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.33711.374
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReedSolomon", "ReedSolomon\ReedSolomon.csproj", "{305A4D2F-A539-4C8D-B6CA-78F7B747A485}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReedSolomon", "ReedSolomon\ReedSolomon.csproj", "{305A4D2F-A539-4C8D-B6CA-78F7B747A485}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReedSolomonTests", "ReedSolomonTests\ReedSolomonTests.csproj", "{A01F9BC0-4E9D-43FA-8965-C08C9C95115D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReedSolomonTests", "ReedSolomonTests\ReedSolomonTests.csproj", "{A01F9BC0-4E9D-43FA-8965-C08C9C95115D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReadmeExample", "ReadmeExample\ReadmeExample.csproj", "{071D3049-0A47-4374-9ADF-01792DC9A356}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
{A01F9BC0-4E9D-43FA-8965-C08C9C95115D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A01F9BC0-4E9D-43FA-8965-C08C9C95115D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A01F9BC0-4E9D-43FA-8965-C08C9C95115D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {071D3049-0A47-4374-9ADF-01792DC9A356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {071D3049-0A47-4374-9ADF-01792DC9A356}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {071D3049-0A47-4374-9ADF-01792DC9A356}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {071D3049-0A47-4374-9ADF-01792DC9A356}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ReedSolomon/ReedSolomon/ReedSolomon.cs b/ReedSolomon/ReedSolomon/ReedSolomon.cs
index 9df73ef..1be4314 100644
--- a/ReedSolomon/ReedSolomon/ReedSolomon.cs
+++ b/ReedSolomon/ReedSolomon/ReedSolomon.cs
@@ -1,4 +1,7 @@
-namespace Witteborn.ReedSolomon;
+using System.Collections.Generic;
+using System.Data.SqlTypes;
+
+namespace Witteborn.ReedSolomon;
///
/// Reed-Solomon Coding over 8-bit values.
@@ -29,6 +32,173 @@ public ReedSolomon(int dataShardCount, int parityShardCount)
}
}
+
+ ///
+ /// This produces a total amount of shards of dataShards + parityShard.
+ /// The Shards are already encoded. Note that the result will be bigger than the data input because of the parity shards being added.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public byte[][] ManagedEncode(byte[] data, int dataShards, int parityShards)
+ {
+ sbyte[] sbyteData = Array.ConvertAll(data, b => unchecked((sbyte)b));
+ var encodedShards = ManagedEncode(sbyteData, dataShards, parityShards);
+
+ var result = new List();
+
+ for (int i = 0; i < encodedShards.Length; i++)
+ {
+ var shard = encodedShards[i];
+ byte[] rawShard = Array.ConvertAll(shard, b => unchecked((byte)b));
+ result.Add(rawShard);
+ }
+
+ return result.ToArray();
+ }
+
+ ///
+ /// This produces a total amount of shards of dataShards + parityShard.
+ /// The Shards are already encoded. Note that the result will be bigger than the data input because of the parity shards being added.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public sbyte[][] ManagedEncode(sbyte[] data, int dataShards, int parityShards)
+ {
+ int totalShards = dataShards + parityShards;
+
+ int shardSize = (int)Math.Ceiling((double)data.Length / dataShards);
+ int totalDataSize = shardSize * dataShards;
+
+ if (totalDataSize > data.Length)
+ {
+ Array.Resize(ref data, totalDataSize);
+ }
+
+ var rs = new ReedSolomon(dataShards, parityShards);
+ var shardsList = new List();
+
+ for (int i = 0; i < dataShards; i++)
+ {
+ sbyte[] shardData = new sbyte[shardSize];
+ Array.Copy(data, i * shardSize, shardData, 0, shardSize);
+ shardsList.Add(shardData);
+ }
+
+ for (int i = dataShards; i < totalShards; i++)
+ {
+ shardsList.Add(new sbyte[shardSize]);
+ }
+ var shards = shardsList.ToArray();
+ rs.EncodeParity(shards, 0, shardSize);
+
+ return shards.ToArray();
+ }
+
+ ///
+ /// This produces a total amount of shards of dataShards + parityShard.
+ /// The Shards are already encoded. Note that the result will be bigger than the data input because of the parity shards being added.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public byte[] ManagedDecode(byte[][] data, int dataShards, int parityShards)
+ {
+ int size = 0;
+
+ sbyte[][] sbytes = new sbyte[data.Length][];
+ for (int i = 0; i < data.Length; i++)
+ {
+ if (size == 0) {
+ if (data[i] != null) {
+ size = data[i].Length;
+ }
+ }
+
+ if (data[i] == null) {
+ data[i] = new byte[size];
+ }
+
+ sbytes[i] = Array.ConvertAll(data[i], b => unchecked((sbyte)b));
+ }
+
+ var result = ManagedDecode(sbytes, dataShards, parityShards);
+ return Array.ConvertAll(result, b => unchecked((byte)b));
+ }
+
+ ///
+ /// This produces a total amount of shards of dataShards + parityShard.
+ /// The Shards are already encoded. Note that the result will be bigger than the data input because of the parity shards being added.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public sbyte[] ManagedDecode(sbyte[][] data, int dataShards, int parityShards)
+ {
+ ReedSolomon rs = new ReedSolomon(dataShards, parityShards);
+ int totalShards = dataShards + parityShards;
+ int shardSize = data[0].Length;
+ bool[] shardPresent = new bool[totalShards];
+
+ for (int i = 0; i < data.Length; i++)
+ {
+ //if any shard is null, create a new array
+ if (data[i] == null || data[i].All(d => d == 0))
+ {
+ data[i] = new sbyte[shardSize];
+ shardPresent[i] = false;
+ }
+ else
+ {
+ shardPresent[i] = true;
+ }
+ }
+
+ bool atleastOneShardIsMissing = shardPresent.Any(b => b == false);
+ if (atleastOneShardIsMissing)
+ {
+ rs.DecodeMissing(data, shardPresent, 0, data[0].Length);
+ }
+
+ var output = new List();
+ for (int i = 0; i < dataShards; i++)
+ {
+ output.AddRange(data[i]);
+ }
+
+ var outputArray = output.ToArray();
+ return outputArray;
+ }
+
+ ///
+ /// Encodes parity for a set of data shards. Note that this is slower than using the sbytes directly
+ ///
+ /// An array containing data shards followed by parity shards.
+ /// Each shard is a byte array, and they must all be the same size
+ /// .
+ /// The index of the first sbyte in each shard to encode.
+ /// The number of sbytes to encode in each shard.
+ public void EncodeParity(byte[][] shards, int offset, int byteCount)
+ {
+ sbyte[][] sbytes = new sbyte[shards.Length][];
+ for (int i = 0; i < shards.Length; i++)
+ {
+ sbytes[i] = Array.ConvertAll(shards[i], b => unchecked((sbyte)b));
+ }
+
+ EncodeParity(sbytes, offset, byteCount);
+
+ for (int i = 0; i < shards.Length; i++)
+ {
+ shards[i] = Array.ConvertAll(sbytes[i], b => unchecked((byte)b));
+ }
+ }
+
///
/// Encodes parity for a set of data shards.
///
diff --git a/ReedSolomon/ReedSolomon/ReedSolomon.csproj b/ReedSolomon/ReedSolomon/ReedSolomon.csproj
index f56facd..fefa667 100644
--- a/ReedSolomon/ReedSolomon/ReedSolomon.csproj
+++ b/ReedSolomon/ReedSolomon/ReedSolomon.csproj
@@ -11,7 +11,7 @@
https://github.com/Witteborn/ReedSolomon
https://github.com/Witteborn/ReedSolomon
True
-
+ 1.1.0
Witteborn
README.md
@@ -20,14 +20,14 @@
-
- True
- \
-
-
- True
- \
-
+
+ True
+ \
+
+
+ True
+ \
+
diff --git a/ReedSolomon/ReedSolomonTests/ReedSolomonTests.cs b/ReedSolomon/ReedSolomonTests/ReedSolomonTests.cs
index d20b362..2c86236 100644
--- a/ReedSolomon/ReedSolomonTests/ReedSolomonTests.cs
+++ b/ReedSolomon/ReedSolomonTests/ReedSolomonTests.cs
@@ -1,3 +1,4 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using Witteborn.ReedSolomon;
namespace ReedSolomonTests
@@ -5,6 +6,103 @@ namespace ReedSolomonTests
[TestClass()]
public class ReedSolomonTests
{
+ [TestMethod()]
+ public void ProduceEncodedShardsTest()
+ {
+ //Arrange
+ ReedSolomon rs = new ReedSolomon(dataShardCount: 4, parityShardCount: 2);
+
+ sbyte[] data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
+
+ var shards = rs.ManagedEncode(data, 4, 2);
+
+ //Assert
+ sbyte[][] expectedShards =
+ [
+ [0, 1, 2, 3],
+ [4, 5, 6, 7],
+ [8, 9, 10, 11],
+ [12, 13, 14, 15],
+ [16, 17, 18, 19],
+ [20, 21, 22, 23]
+ ];
+
+ for (int i = 0; i < shards.Length; i++)
+ {
+ Assert.IsTrue(shards[i].SequenceEqual(expectedShards[i]));
+ }
+ }
+
+ [TestMethod()]
+ public void ProduceEncodedShardsTest2()
+ {
+ //Arrange
+ ReedSolomon rs = new ReedSolomon(dataShardCount: 4, parityShardCount: 2);
+
+ byte[] data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
+
+ //Act
+ var shards = rs.ManagedEncode(data, 4, 2);
+
+ //Assert
+ byte[][] expectedShards =
+ [
+ [0, 1, 2, 3],
+ [4, 5, 6, 7],
+ [8, 9, 10, 11],
+ [12, 13, 14, 15],
+ [16, 17, 18, 19],
+ [20, 21, 22, 23]
+ ];
+
+ for (int i = 0; i < shards.Length; i++)
+ {
+ Assert.IsTrue(shards[i].SequenceEqual(expectedShards[i]));
+ }
+ }
+
+ [TestMethod()]
+ public void ConvertedEncodeParityTest()
+ {
+ //Arrange
+ ReedSolomon rs = new ReedSolomon(dataShardCount: 4, parityShardCount: 2);
+
+ byte[] data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
+
+ List shardsList = new();
+ for (int i = 0; i < 4; i++)
+ {
+ var segment = new ArraySegment(data, data.Length / 4 * i, data.Length / 4);
+ shardsList.Add(segment.ToArray());
+ }
+
+ for (int i = 0; i < 2; i++)
+ {
+ shardsList.Add(new byte[data.Length / 4]);
+ }
+
+ var shards = shardsList.ToArray();
+
+ //Act
+ rs.EncodeParity(shards, 0, data.Length / 4);
+
+ //Assert
+ byte[][] expectedShards =
+ [
+ [0, 1, 2, 3],
+ [4, 5, 6, 7],
+ [8, 9, 10, 11],
+ [12, 13, 14, 15],
+ [16, 17, 18, 19],
+ [20, 21, 22, 23]
+ ];
+
+ for (int i = 0; i < shards.Length; i++)
+ {
+ Assert.IsTrue(shards[i].SequenceEqual(expectedShards[i]));
+ }
+ }
+
[TestMethod()]
public void EncodeParityTest()
{
@@ -47,6 +145,66 @@ public void EncodeParityTest()
}
}
+ [TestMethod()]
+ public void Decode_OneShard_Success_Test()
+ {
+ //Arrange
+ ReedSolomon rs = new ReedSolomon(dataShardCount: 4, parityShardCount: 2);
+
+ sbyte[][] shards =
+ [
+ [0, 1, 2, 3], //Data
+ [0, 0, 0, 0], //Missing Data
+ [8, 9, 10, 11], //Data
+ [12, 13, 14, 15], //Data
+ [16, 17, 18, 19], //Parity
+ [20, 21, 22, 23] //Parity
+ ];
+
+
+ //Act
+ var result = rs.ManagedDecode(shards, 4, 2);
+
+ //Assert
+ sbyte[] expected =
+ [0, 1, 2, 3, //Data
+ 4, 5, 6, 7, //Data
+ 8, 9, 10, 11, //Data
+ 12, 13, 14, 15]; //Data
+
+ Assert.IsTrue(result.SequenceEqual(expected));
+ }
+
+ [TestMethod()]
+ public void Decode_OneShard_Success_Test2()
+ {
+ //Arrange
+ ReedSolomon rs = new ReedSolomon(dataShardCount: 4, parityShardCount: 2);
+
+ byte[][] shards =
+ [
+ [0, 1, 2, 3], //Data
+ [0, 0, 0, 0], //Missing Data
+ [8, 9, 10, 11], //Data
+ [12, 13, 14, 15], //Data
+ [16, 17, 18, 19], //Parity
+ [20, 21, 22, 23] //Parity
+ ];
+
+
+ //Act
+ var result = rs.ManagedDecode(shards, 4, 2);
+
+ //Assert
+ byte[] expected =
+ [0, 1, 2, 3, //Data
+ 4, 5, 6, 7, //Data
+ 8, 9, 10, 11, //Data
+ 12, 13, 14, 15]; //Data
+
+ Assert.IsTrue(result.SequenceEqual(expected));
+ }
+
[TestMethod()]
public void DecodeMissing_OneShard_Success_Test()
{