using System;
namespace Legalsoft.Truffer
{
/// <summary>
/// 循环冗余校验和
/// cyclic redundancy checksum
/// </summary>
public class Icrc
{
private uint jcrc { get; set; }
private uint jfill { get; set; }
private uint poly { get; set; }
private static uint[] icrctb { get; set; } = new uint[256];
public Icrc(int jpoly, bool fill = true)
{
this.jfill = (uint)(fill ? 255 : 0);
uint[] okpolys = {
0x755B, 0xA7D3, 0x8005, 0x1021,
0x5935, 0x90D9, 0x5B93, 0x2D17
};
poly = okpolys[jpoly & 7];
for (int j = 0; j < 256; j++)
{
icrctb[j] = icrc1((uint)(j << 8), 0);
}
jcrc = (jfill | (jfill << 8));
}
public uint crc(string bufptr)
{
jcrc = (jfill | (jfill << 8));
return concat(bufptr);
}
public uint concat(string bufptr)
{
uint cword = jcrc;
uint len = (uint)bufptr.Length;
for (int j = 0; j < len; j++)
{
cword = (uint)(icrctb[(byte)bufptr[j] ^ hibyte((ushort)cword)] ^ (lobyte((ushort)cword) << 8));
}
return jcrc = cword;
}
public uint icrc1(uint jcrc, byte onech)
{
uint ans = (uint)(jcrc ^ onech << 8);
for (int i = 0; i < 8; i++)
{
if ((ans & 0x8000) != 0)
{
ans = (uint)((ans <<= 1) ^ poly);
}
else
{
ans <<= 1;
}
ans &= 0xffff;
}
return ans;
}
public byte lobyte(ushort x)
{
return (byte)(x & 0xff);
}
public byte hibyte(ushort x)
{
return (byte)((x >> 8) & 0xff);
}
public static bool decchk(string str, ref char ch)
{
int[,] decchk_ip =
{
{0, 1, 5, 8, 9, 4, 2, 7},
{1, 5, 8, 9, 4, 2, 7, 0},
{2, 7, 0, 1, 5, 8, 9, 4},
{3, 6, 3, 6, 3, 6, 3, 6},
{4, 2, 7, 0, 1, 5, 8, 9},
{5, 8, 9, 4, 2, 7, 0, 1},
{6, 3, 6, 3, 6, 3, 6, 3},
{7, 0, 1, 5, 8, 9, 4, 2},
{8, 9, 4, 2, 7, 0, 1, 5},
{9, 4, 2, 7, 0, 1, 5, 8}
};
int[,] decchk_ij =
{
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
{1, 2, 3, 4, 0, 6, 7, 8, 9, 5},
{2, 3, 4, 0, 1, 7, 8, 9, 5, 6},
{3, 4, 0, 1, 2, 8, 9, 5, 6, 7},
{4, 0, 1, 2, 3, 9, 5, 6, 7, 8},
{5, 9, 8, 7, 6, 0, 4, 3, 2, 1},
{6, 5, 9, 8, 7, 1, 0, 4, 3, 2},
{7, 6, 5, 9, 8, 2, 1, 0, 4, 3},
{8, 7, 6, 5, 9, 3, 2, 1, 0, 4},
{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
};
int k = 0;
int m = 0;
int n = str.Length;
int j;
for (j = 0; j < n; j++)
{
char c = str[j];
if (c >= 48 && c <= 57)
{
k = decchk_ij[k, decchk_ip[(c + 2) % 10, 7 & m++]];
}
}
for (j = 0; j < 10; j++)
{
if (decchk_ij[k, decchk_ip[j, m & 7]] == 0)
{
break;
}
}
ch = (char)(j + 48);
return k == 0;
}
}
}