Files
cuetools.net/CUETools.Ripper.SCSI/Galois.cs

189 lines
6.2 KiB
C#
Raw Normal View History

2008-12-03 21:42:22 +00:00
<EFBFBD><EFBFBD>using System;
using System.Collections.Generic;
using System.Text;
namespace CUETools.Ripper.SCSI
{
public class Galois
{
public const int POLYNOMIAL = 0x1d;
public static Galois instance = new Galois();
private int[] expTbl = new int[255 * 2]; // <EFBFBD>N͑k0<EFBFBD>0d0S0h0k0<EFBFBD>0<EFBFBD>0mul, divI{<EFBFBD>0!|euS
private int[] logTbl = new int[255 + 1];
/**
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>00<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD>v<EFBFBD>N Y<EFBFBD>c<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n0\Ob
*/
Galois()
{
int d = 1;
for (int i = 0; i < 255; i++)
{
expTbl[i] = expTbl[255 + i] = d;
logTbl[d] = i;
d <<= 1;
if ((d & 0x100) != 0)
{
d = (d ^ POLYNOMIAL) & 0xff;
}
}
}
/**
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0 -> <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0 Y<EFBFBD>c
*
* @param a int
* @return int
*/
public int toExp(int a)
{
return expTbl[a];
}
/**
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0 -> <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0 Y<EFBFBD>c
*
* @param a int
* @return int
*/
public int toLog(int a)
{
return logTbl[a];
}
/**
* <EFBFBD><EFBFBD><EFBFBD>0MOn<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD><EFBFBD>{
*
* @param length int
* <EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>
* @param a int
* <EFBFBD><EFBFBD><EFBFBD>0MOn<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
* @return int
* <EFBFBD><EFBFBD><EFBFBD>0MOn<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
*/
public int toPos(int length, int a)
{
return length - 1 - logTbl[a];
}
/**
* <EFBFBD>cQ0<EFBFBD>{
*
* @param a int
* @param b int
* @return int
* = a * b
*/
public int mul(int a, int b)
{
return (a == 0 || b == 0) ? 0 : expTbl[logTbl[a] + logTbl[b]];
}
/**
* <EFBFBD>cQ0<EFBFBD>{
*
* @param a int
* @param b int
* @return int
* = a * <EFBFBD>^b
*/
public int mulExp(int a, int b)
{
return (a == 0) ? 0 : expTbl[logTbl[a] + b];
}
/**
* rR<EFBFBD>0<EFBFBD>{
*
* @param a int
* @param b int
* @return int
* = a / b
*/
public int div(int a, int b)
{
return (a == 0) ? 0 : expTbl[logTbl[a] - logTbl[b] + 255];
}
/**
* rR<EFBFBD>0<EFBFBD>{
*
* @param a int
* @param b int
* @return int
* = a / <EFBFBD>^b
*/
public int divExp(int a, int b)
{
return (a == 0) ? 0 : expTbl[logTbl[a] - b + 255];
}
/**
* <EFBFBD>pe
*
* @param a int
* @return int
* = 1/a
*/
public int inv(int a)
{
return expTbl[255 - logTbl[a]];
}
/**
* pe_n0<EFBFBD>cQ0<EFBFBD>{
*
* @param seki int[]
* seki = a * b
* @param a int[]
* @param b int[]
*/
public void mulPoly(int[] seki, int[] a, int[] b)
{
Array.Clear(seki, 0, seki.Length);
for (int ia = 0; ia < a.Length; ia++)
{
if (a[ia] != 0)
{
int loga = logTbl[a[ia]];
int ib2 = Math.Min(b.Length, seki.Length - ia);
for (int ib = 0; ib < ib2; ib++)
{
if (b[ib] != 0)
{
seki[ia + ib] ^= expTbl[loga + logTbl[b[ib]]]; // = a[ia] * b[ib]
}
}
}
}
}
/**
* <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0n0<EFBFBD><EFBFBD>{
* @param data int[]
* eQ<EFBFBD>R<EFBFBD>0<EFBFBD>0<EFBFBD>0M<EFBFBD>R
* @param length int
* <EFBFBD>0<EFBFBD>0<EFBFBD>0w<EFBFBD>
* @param syn int[]
* (x - <EFBFBD>^0) (x - <EFBFBD>^1) (x - <EFBFBD>^2) ...n0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
* @return boolean
* true: <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0o0<EFBFBD>}f00
*/
public bool calcSyndrome(byte[] data, int length, int[] syn)
{
int hasErr = 0;
for (int i = 0; i < syn.Length; i++)
{
int wk = 0;
for (int idx = 0; idx < length; idx++)
{
wk = data[idx] ^ ((wk == 0) ? 0 : expTbl[logTbl[wk] + i]); // wk = data + wk * <EFBFBD>^i
}
syn[i] = wk;
hasErr |= wk;
}
return hasErr == 0;
}
}
}