Files
Toolkit2/Toolkit.UI.Controls.Avalonia/QrCode/Encoding/ReedSolomon/GaloisField256.cs
T
TheXamlGuy bc55c4649b tidy
2024-04-26 23:05:36 +01:00

120 lines
2.9 KiB
C#

namespace Gma.QrCodeNet.Encoding.ReedSolomon;
/// <summary>
/// Description of GaloisField256.
/// </summary>
internal sealed class GaloisField256
{
internal GaloisField256(int primitive)
{
AntiLogTable = new int[256];
LogTable = new int[256];
Primitive = primitive;
int gfx = 1;
// Power cycle is from 0 to 254. 2^255 = 1 = 2^0
// Value cycle is from 1 to 255. Thus there should not have Log(0).
for (int powers = 0; powers < 256; powers++)
{
AntiLogTable[powers] = gfx;
if (powers != 255)
{
LogTable[gfx] = powers;
}
gfx <<= 1; // gfx = gfx * 2 where alpha is 2.
if (gfx > 255)
{
gfx ^= primitive;
}
}
}
private int[] AntiLogTable { get; }
private int[] LogTable { get; }
internal int Primitive { get; }
internal static GaloisField256 QRCodeGaloisField => new(QRCodeConstantVariable.QRCodePrimitive);
/// <returns>
/// Powers of a in GF table. Where a = 2
/// </returns>
internal int Exponent(int powersOfa) => AntiLogTable[powersOfa];
/// <returns>
/// Log (power of a) in GF table. Where a = 2
/// </returns>
internal int Log(int gfValue)
{
if (gfValue == 0)
{
throw new ArgumentException("GaloisField value will not be equal to 0, Log method.");
}
return LogTable[gfValue];
}
internal int Inverse(int gfValue)
{
if (gfValue == 0)
{
throw new ArgumentException("GaloisField value will not be equal to 0, Inverse method.");
}
return Exponent(255 - Log(gfValue));
}
internal int Addition(int gfValueA, int gfValueB) => gfValueA ^ gfValueB;
internal int Subtraction(int gfValueA, int gfValueB) => Addition(gfValueA, gfValueB); // Subtraction is same as addition.
/// <returns>
/// Product of two values.
/// In other words. a multiply b
/// </returns>
internal int Product(int gfValueA, int gfValueB)
{
if (gfValueA == 0 || gfValueB == 0)
{
return 0;
}
if (gfValueA == 1)
{
return gfValueB;
}
if (gfValueB == 1)
{
return gfValueA;
}
return Exponent((Log(gfValueA) + Log(gfValueB)) % 255);
}
/// <returns>
/// Quotient of two values.
/// In other words. a divided b
/// </returns>
internal int Quotient(int gfValueA, int gfValueB)
{
if (gfValueA == 0)
{
return 0;
}
if (gfValueB == 0)
{
throw new ArgumentException($"{nameof(gfValueB)} cannot be zero.");
}
if (gfValueB == 1)
{
return gfValueA;
}
return Exponent(Math.Abs(Log(gfValueA) - Log(gfValueB)) % 255);
}
}