CRC中流而不是结束

时间:2016-05-10 21:59:42

标签: crc

通常,人们会在数据流的末尾添加CRC。 CRC校验将包括CRC本身,如果CRC正确则返回0。

我需要添加CRC来验证我的嵌入代码。需要对其进行检查,但内存空间中的首字是中断向量。是否可以在中间放置一个键值,以便CRC校验为整个代码返回0? (或者这是无法解决的?)

1 个答案:

答案 0 :(得分:2)

这绝对有可能。您可以向后运行CRC,这将是快速和简单的。下面是示例代码。

实际上,您可以在流中的任何位置给我分散位的位置,如果您给我足够的位数,我可以告诉您如何设置它们以在结尾处获得零CRC或任何其他CRC这个问题的价值。我的spoof code解决了线性方程式,得出了答案。

但是我想知道你为什么要这样做。为什么不知道CRC的存储位置并计算除此之外的所有内容的CRC,然后根据存储的CRC检查结果?

// Example of the generation of a "middle" CRC, which is inserted somewhere in
// the middle of a sequence, where the CRC is generated such that the CRC of
// the complete sequence will be zero. This particular CRC has no pre or post
// processing.
//
// Placed into the public domain by Mark Adler, 11 May 2016.

#include <stddef.h>         // for size_t
#include <stdint.h>         // for uint32_t and uint64_t

#define POLY 0xedb88320     // CRC polynomial

// Byte-wise CRC tables for forward and reverse calculations.
uint32_t crc_forward_table[256];
uint32_t crc_reverse_table[256];

// Fill in CRC tables using bit-wise calculations.
void crc32_make_tables(void) {
    for (uint32_t n = 0; n < 256; n++) {
        uint32_t crc = n;
        for (int k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc_forward_table[n] = crc;
        crc_reverse_table[crc >> 24] = (crc << 8) ^ n;
    }
}

// Return the forward CRC of buf[0..len-1], starting with crc at the front.
uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len) {
    for (size_t n = 0; n < len; n++)
        crc = (crc >> 8) ^ crc_forward_table[(crc ^ buf[n]) & 0xff];
    return crc;
}

// Return the reverse CRC of buf[0..len-1], starting with crc at the end.
uint32_t crc32_reverse(uint32_t crc, unsigned char *buf, size_t len) {
    while (len)
        crc = (crc << 8) ^ crc_reverse_table[crc >> 24] ^ buf[--len];
    return crc;
}

// Put a 32-bit value into a byte buffer in little-endian order.
void put4(uint32_t word, unsigned char *pos) {
    pos[0] = word;
    pos[1] = word >> 8;
    pos[2] = word >> 16;
    pos[3] = word >> 24;
}

#include <stdlib.h>         // for random() and srandomdev()

// Fill dat[0..len-1] with uniformly random byte values. All of the bits from
// each random() call are used, except for possibly a few leftover at the end.
void ranfill(unsigned char *dat, size_t len) {
    uint64_t ran = 1;
    while (len) {
        if (ran < 0x100)
            ran = (ran << 31) + random();
        *dat++ = ran;
        ran >>= 8;
        len--;
    }
}

#include <stdio.h>          // for printf()

#define LEN 1024            // length of the message without the CRC

// Demonstrate the generation of a middle-CRC, using the forward and reverse
// CRC computations. Verify that the CRC of the resulting sequence is zero.
int main(void) {
    crc32_make_tables();
    srandomdev();
    unsigned char dat[LEN+4];
    ranfill(dat, LEN/2);
    put4(0, dat + LEN/2);       // put zeros where the CRC will go
    ranfill(dat + LEN/2 + 4, (LEN+1)/2);
    put4(crc32(0, dat, LEN/2) ^ crc32_reverse(0, dat + LEN/2, (LEN+1)/2 + 4),
         dat + LEN/2);          // replace the zeros with the CRC
    printf("%08x\n", crc32(0, dat, LEN+4));
    return 0;
}