有谁有 C++ 中的 CRC128 和 CRC256 代码吗?和C#?

发布于 2024-09-15 11:04:37 字数 192 浏览 11 评论 0原文

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

I am learning, trying to get thoughts behind CRC. I can't find CRC128 and CRC256 code anywhere. If anyone of you have the C++ or C# Code for them, please share them with me. Also provide online links to the websites. I am a newbie and can't code it by myself at all, neither can convert theories and mathematics to the coding. So I ask for help from you. It will be so nice of you who provide me the proper and simple codes. If anyone provides me these codes, please do also provide CRC Table generator functions. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

唱一曲作罢 2024-09-22 11:04:37

尽管定义了 CRC-128 和 CRC-256,但我不知道有谁真正使用它们。

大多数时候,认为自己需要 CRC 的开发人员实际上应该使用加密哈希函数 ,它已经在许多应用中成功地实现了 CRC。在极少数情况下,CRC-128 或 CRC-256 甚至比损坏的 MD5 更优越,更不用说 SHA-2 系列了。

Though CRC-128 and CRC-256 were defined, I don't know of anyone who actually uses them.

Most of the time, developers who think they want a CRC should really be using a cryptographic hash function, which have succeeded CRCs for many applications. It would be a rare case indeed where CRC-128 or CRC-256 would be a superior choice to even the broken MD5, much less the SHA-2 family.

帅哥哥的热头脑 2024-09-22 11:04:37

我同意你的观点,只是对于 32 位和 64 位 CRC,意外冲突率分别高于 2^32 分之一或 2^64 分之一。

我编写了一个应用程序,通过 CRC 值来跟踪事物,以跟踪项目。我们需要跟踪潜在的数百万个项目,我们从 CRC32 开始,在现实世界的实践中,其冲突率约为 2^16 中的 1,这是一个令人不快的意外。然后我们重新编码以使用 CRC64,其实际冲突率约为 2^23 中的 1。我们在对 32 位版本感到不愉快之后对此进行了测试,并接受了 64 位版本的较小错误率。

我无法真正解释预期冲突率背后的统计数据,但有道理的是,您会比位宽度更快地经历碰撞。就像哈希表一样...一些哈希桶是空的,而另一些哈希桶有多个条目...

即使对于 256 位 CRC,前 2 个 CRC 也可能是相同的...这几乎令人难以置信,但却是可能的。

I agree with you except that the accidental collision rate is higher than 1 in 2^32 or 1 in 2^64 for 32 bit and 64 bit CRCs respectively.

I wrote an app that kept track of things by their CRC values for tracking items. We needed to track potentially millions of items and we started with a CRC32 which in real world practice has a collision rate of around 1 in 2^16 which was an unpleasant surprise. We then re-coded to use a CRC64 which had a real world collision rate of about 1 in 2^23. We tested this after the unpleasant surprise of the 32 bit one we started with and accepted the small error rate of the 64 bit one.

I can't really explain the statistics behind the expected collision rate but it makes sense that you would experience a collision much sooner that the width of the bits. Just like a hashtable...some hash buckets are empty and others have more than one entry....

Even for a 256 bit CRC the first 2 CRC's could be the same...it would be almost incredible but possible.

路还长,别太狂 2024-09-22 11:04:37

这是我最近编写的一个用于处理 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();
}
}

Here is a Java class I wrote recently for playing with CRCs. Beware that changing the bit order is implemented only for bitwise computation.

/**
 * 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();
}
}
忘羡 2024-09-22 11:04:37

仅当以下三点为真时,CRC-128 和 CRC-256 才有意义:

  1. 您的 CPU 受限于加密哈希会显着降低速度的程度
  2. 统计上绝不能发生意外冲突,2^64 中的 1 仍然太高
  3. OTOH 故意冲突不是问题

2 和 3 可以同时成立的典型情况是,如果意外冲突会造成数据丢失,则只会影响数据发送者,而不影响平台。

CRC-128 and CRC-256 only make sense if the three following point are true :

  1. You are CPU constrained to the point where a crypto hash would significantly slow you down
  2. Accidental collision must statistically never happen, 1 in 2^64 is still too high
  3. OTOH deliberate collisions are not a problem

A typical case where 2 and 3 can be true together is if an accidental collision would create a data loss that only affects the sender of the data, and not the platform.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文