120 lines
2.9 KiB
C#
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);
|
|
}
|
|
} |