有没有人用C ++和C#编写CRC128和CRC256代码?

时间:2010-08-23 18:34:49

标签: c# algorithm hash crc crc32

我正在学习,试图了解CRC背后的想法。我无法在任何地方找到CRC128和CRC256代码。如果你们中的任何人都有C ++或C#代码,请与我分享。还提供网站的在线链接。我是一个新手,根本不能自己编码,也不能将理论和数学转换成编码。所以我向你寻求帮助。你能为我提供正确而简单的代码真是太好了。如果有人向我提供这些代码,请同时提供CRC表生成器功能。谢谢。

4 个答案:

答案 0 :(得分:3)

这是我最近为了与CRC一起玩的Java类。请注意,更改位顺序仅适用于按位计算。

/**
 * A CRC algorithm for computing check values.
 */
public class Crc
{
public static final Crc CRC_16_CCITT =
    new Crc(16, 0x1021, 0xffff, 0xffff, true);
public static final Crc CRC_32 =
    new Crc(32, 0x04c11db7, 0xffffffffL, 0xffffffffL, true);


private final int _width;
private final long _polynomial;
private final long _mask;
private final long _highBitMask;
private final long _preset;
private final long _postComplementMask;
private final boolean _msbFirstBitOrder;
private final int _shift;

private final long[] _crcs;



/**
 * Constructs a CRC specification.
 *
 * @param width
 * @param polynomial
 * @param msbFirstBitOrder
 */
public Crc(
    int width,
    long polynomial)
{
    this(width, polynomial, 0, 0, true);
}


/**
 * Constructs a CRC specification.
 *
 * @param width
 * @param polynomial
 * @param msbFirstBitOrder
 */
public Crc(
    int width,
    long polynomial,
    long preset,
    long postComplementMask,
    boolean msbFirstBitOrder)
{
    super();
    _width = width;
    _polynomial = polynomial;
    _mask = (1L << width) - 1;
    _highBitMask = (1L << (width - 1));
    _preset = preset;
    _postComplementMask = postComplementMask;
    _msbFirstBitOrder = msbFirstBitOrder;
    _shift = _width - 8;

    _crcs = new long[256];
    for (int i = 0; i < 256; i++)
    {
        _crcs[i] = crcForByte(i);
    }
}


/**
 * Gets the width.
 *
 * @return  The width.
 */
public int getWidth()
{
    return _width;
}


/**
 * Gets the polynomial.
 *
 * @return  The polynomial.
 */
public long getPolynomial()
{
    return _polynomial;
}


/**
 * Gets the mask.
 *
 * @return  The mask.
 */
public long getMask()
{
    return _mask;
}


/**
 * Gets the preset.
 *
 * @return  The preset.
 */
public long getPreset()
{
    return _preset;
}


/**
 * Gets the post-complement mask.
 *
 * @return  The post-complement mask.
 */
public long getPostComplementMask()
{
    return _postComplementMask;
}


/**
 * @return  True if this CRC uses MSB first bit order.
 */
public boolean isMsbFirstBitOrder()
{
    return _msbFirstBitOrder;
}


public long computeBitwise(byte[] message)
{
    long result = _preset;

    for (int i = 0; i < message.length; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            final int bitIndex = _msbFirstBitOrder ? 7 - j : j;
            final boolean messageBit = (message[i] & (1 << bitIndex)) != 0;
            final boolean crcBit = (result & _highBitMask) != 0;

            result <<= 1;
            if (messageBit ^ crcBit)
            {
                result ^= _polynomial;
            }
            result &= _mask;
        }
    }

    return result ^ _postComplementMask;
}


public long compute(byte[] message)
{
    long result = _preset;

    for (int i = 0; i < message.length; i++)
    {
        final int b = (int) (message[i] ^ (result >>> _shift)) & 0xff;

        result = ((result << 8) ^ _crcs[b]) & _mask;
    }
    return result ^ _postComplementMask;
}


private long crcForByte(int b)
{
    long result1 = (b & 0xff) << _shift;
    for (int j = 0; j < 8; j++)
    {
        final boolean crcBit = (result1 & (1L << (_width - 1))) != 0;

        result1 <<= 1;
        if (crcBit)
        {
            result1 ^= _polynomial;
        }
        result1 &= _mask;
    }
    return result1;
}


public String crcTable()
{
    final int digits = (_width + 3) / 4;
    final int itemsPerLine = (digits + 4) * 8 < 72 ? 8 : 4;

    final String format = "0x%0" + digits + "x, ";

    final StringBuilder builder = new StringBuilder();
    builder.append("{\n");
    for (int i = 0; i < _crcs.length; i += itemsPerLine)
    {
        builder.append("    ");
        for (int j = i; j < i + itemsPerLine; j++)
        {
            builder.append(String.format(format, _crcs[j]));
        }
        builder.append("\n");
    }
    builder.append("}\n");
    return builder.toString();
}
}

答案 1 :(得分:2)

虽然定义了CRC-128和CRC-256,但我不知道有谁实际使用它们。

大多数情况下,认为他们想要CRC的开发人员应该使用cryptographic hash function,它已成功为许多应用程序提供了CRC。确实,CRC-128或CRC-256即使是破碎的MD5也是一个优秀的选择,更不用说SHA-2系列了。

答案 2 :(得分:2)

CRC-128和CRC-256只有在以下三点成立时才有意义:

  1. 您的CPU受限于加密哈希会显着降低您的速度
  2. 在统计上绝不会发生意外碰撞,1 ^ 2 64仍然太高
  3. OTOH故意碰撞不是问题
  4. 2和3可以一起为真的典型情况是,如果意外碰撞会造成数据丢失,只会影响数据的发送者,而不会影响平台。

答案 3 :(得分:1)

我同意你的意见,除了意外碰撞率分别高于2 ^ 32中的1或32位和64位CRC中的1 ^ 2 ^ 64。

我写了一个应用程序,通过CRC值跟踪事物来跟踪项目。我们需要追踪数百万件物品,我们从CRC32开始,在实际操作中碰撞率约为1比2 ^ 16,这是一个令人不快的惊喜。然后我们重新编码以使用CRC64,其实际碰撞率约为1 ^ 2 ^ 23。在我们开始使用32位的令人不快的惊喜之后我们对此进行了测试,并接受了64位的错误率。

我无法真正解释预期碰撞率背后的统计数据,但有意义的是,您会在比特宽度之前更快地发生碰撞。就像哈希表一样......一些哈希桶是空的,而其他哈希桶有多个条目......

即使对于256位CRC,前两个CRC也可能是相同的...它几乎是不可思议但可能的。