C#,数值计算——循环冗余校验和(CRC,Cyclic Redundancy Checksum)的计算方法与源代码

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;
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/131445573