Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

which is CRC-16-CCITT? #54

Closed
clouds56 opened this issue Jul 31, 2020 · 10 comments
Closed

which is CRC-16-CCITT? #54

clouds56 opened this issue Jul 31, 2020 · 10 comments

Comments

@clouds56
Copy link

How to calculate the well known CRC-16-CCITT with poly = 0x1021?
according to https://www.lammertbies.nl/comm/info/crc-calculation and http://srecord.sourceforge.net/crc16-ccitt.html, we shall get 0xE5CC or 0x29B1 for bytes b"123456789", but I could not manage to get it.
The combination I've tried the combination of poly in [0x8408, 0x1021] and init in [0, !0x1D0F], but with no luck.

  fn digest_crc(init: u16, poly: u16, input: &[u8]) -> u16 {
    use crc::crc16::Hasher16;
    let mut digest = crc::crc16::Digest::new_with_initial(poly, init);
    digest.write(input);
    !digest.sum16()
  }
  let input = b"123456789";
  digest_crc(0, 0x1021, input);
  digest_crc(0, 0x8408, input);
  digest_crc(!0x1D0F, 0x1021, input);
  digest_crc(!0x1D0F, 0x8408, input);

I even tried poly of [0x811, 0x8810] according to this https://en.wikipedia.org/wiki/Cyclic_redundancy_check.

@osialr
Copy link

osialr commented Aug 2, 2020

@clouds56 Similar issue, I couldn't get the right combo using crc-rs 1.8. But crc16 AUG_CCITT matches the 0xE5CC output and CCITT-FALSE matched 0x29B1.

// crc16 = "0.4"

const TEST_CASES : &[(&[u8], u16)] = &[
    (b"123456789", 0xE5CC),
    (&[65], 0x9479),
    (&[3, 5, 11], 1730),
    (&['A' as u8; 256], 0xE938),
];

for &(input, expected) in TEST_CASES.iter() {
    let mut state = crc16::State::<crc16::AUG_CCITT>::new();
    state.update(input);
    assert_eq!(state.get(), expected);
}

assert_eq!(crc16::State::<crc16::CCITT_FALSE>::calculate(b"123456789"), 0x29B1);

@clouds56
Copy link
Author

clouds56 commented Aug 7, 2020

@osialr , thanks for the link, according to code in crc16
I think there's 2 way to calculate crc (maybe just like little endian and big endian, while it is about bit order other than byte order),

// (BIT_REVERSE_TABLE[(crc & 0xFF) as usize] << 8) | BIT_REVERSE_TABLE[(crc >> 8) as usize]
crc = ((crc >> 8) | ((msg[i] as u16) << 8)) ^ $table[(crc & 0xff) as usize]

and

crc = ((crc << 8) | (msg[i] as u16)) ^ $table[((crc >> 8) & 0xFF) as usize];

I think it impossible to use this crc crate to get 0xE5CC or 0x29B1 now.

@mrhooray
Copy link
Owner

mrhooray commented Aug 8, 2020

Please see #45 and #48 and help us get traction there. It requires quite an investment and it would be ideal to do it when related pieces are stabilized in Rust.

If you're interested in taking a phased approach and improve compatibility on top current implementation, you're welcome to contribute.

@akhilles
Copy link
Collaborator

@clouds56 this should be possible with the v2 API. I have a working draft @ #55 but it requires Rust beta (for if/loop statements in const_fn).

@mrhooray
Copy link
Owner

#55 has been merged. @clouds56 could you check out the latest master?

@akhilles
Copy link
Collaborator

@mrhooray wdyt about publishing a release candidate 2.0.0-rc.1?

@mrhooray
Copy link
Owner

mrhooray commented Aug 20, 2020

Published 2.0.0-rc.1. There were some timeouts/hiccups - please help check from your end.

@ratijas
Copy link

ratijas commented Nov 12, 2021

So, in the end, in crc-v2.1.0, which is the right one for CRC16-CCITT?

@ratijas
Copy link

ratijas commented Nov 12, 2021

Upon a closer look at the catalogue sources, sounds like this is the one:

https://github.com/akhilles/crc-catalog/blob/95b87f3e7d6b411084ed1190ababc10206bc7b81/src/catalog.rs#L60

/* slightly trimmed from rusty details */
CRC_16_IBM_3740 { poly: 0x1021, init: 0xffff, refin: false, refout: false, xorout: 0x0000, check: 0x29b1, residue: 0x0000 };

http://srecord.sourceforge.net/crc16-ccitt.html

This page presents accurate implementations (long-hand and programmed) of the 16-bit CRC-CCITT specification, which is:

  • Width = 16 bits
  • Truncated polynomial = 0x1021
  • Initial value = 0xFFFF
  • Input data is NOT reflected
  • Output CRC is NOT reflected
  • No XOR is performed on the output CRC

Am I right?

In which case, why won't we have an alias for it?

@akhilles
Copy link
Collaborator

CCITT is confusing because it's commonly misrepresented. You probably want CRC-16/KERMIT if init=0x0000 and CRC-16/IBM-3740 if init=0xffff.

We shouldn't have an alias for CCITT because it's not clear what the "correct" poly and init values are. It's better to use the less ambiguous terms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants