CRC32 with custom Algorithm

Hi,
i would have a crc code with the polynomial as follows:
0xEDB88320
I tried to customize the crc32 algorithm using a predefined crate:

const CUSTOM_ALG: Algorithm<u32> = Algorithm {
    width: 32,
    poly: 0xEDB88320,
    init: 0x00000000,
    refin: false,
    refout: false,
    xorout: 0xffffffff,
    check: 0x00000000,
    residue: 0x00000000,
};

fn crc_gen(){
    let crc = Crc::<u32>::new(&CUSTOM_ALG);
    let mut digest = crc.digest();
     digest.update(&[0xDA; 0x16;0x22;0xB4]); //DA 16 22 B4 in bytes
     let mycrc_calc = digest.finalize();
     println!("my first byte {:x}",218 as u8); // 
    println!("crc final {:x}",mycrc_calc);
}

So, when i obtain the result it is wrong. I don't undersrtand if the customize algorithm is uncorrect or it is uncorrect other parts.

What is the expected output? What library are you using to obtain the expected output?

the solution is 96 68 B8 1B.

i'm using this use crc::{Crc, Algorithm};

I get the same result from your code as from an online JavaScript CRC calculator (0x6F6EE1BF). I would reconsider why you expect the output that you do, it seems unlikely that two unrelated implementations are wrong in the same exact way (though not impossible). I did modify your code a little before running it, because it doesn't compile as is:

error: literal out of range for `u8`
  --> src/main.rs:17:21
   |
17 |     digest.update(&[0xDA1622B4]); //DA 16 22 B4 in bytes
   |                     ^^^^^^^^^^
   |
   = note: the literal `0xDA1622B4` (decimal `3658883764`) does not fit into the type `u8` and will become `180u8`
   = help: consider using the type `u32` instead
   = note: `#[deny(overflowing_literals)]` on by default

So I changed the input to &[0xDA, 0x16, 0x22, 0xB4] instead. Though I don't get 96 68 B8 1B either way so this probably isn't the root of the issue.

1 Like

So it looks like your 0xedb88320 is not a normal polynomial but a reversed polynomial. The corresponding normal polynomial is 0x04c11db7, perhaps the most common CRC-32 polynomial. Therefore, you can use one of the predefined algorithms for this:

use crc::{Crc, CRC_32_ISO_HDLC};

fn main() {
    let crc = Crc::<u32>::new(&CRC_32_ISO_HDLC);
    let checksum = crc.checksum(&[0xda, 0x16, 0x22, 0xb4]);
    println!("{checksum:#x}");
}

This prints 0x1bb86896, which in little-endian order is 96 68 B8 1B, as expected. (To get the checksum in little-endian form, you can call checksum.to_le_bytes().)

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.