Closed akhilles closed 3 years ago
cc @mrhooray @zachmse
Consider implementing std::hash::Hasher
? Related: #8
Updated to implement core::hash::Hasher
to preserve no_std
Can make_table
and thus new
be const
, so that a Crc<_>
can be either created static const
(with its table and constants in ROM on microprocessors) in addition to being constructable (preferably once, but as I read the API it's up to the user to make this happen only once) in RAM at runtime?
I'd be happy with this API, especially if the above can be arranged.
I figure that tables for the common algorithms would just all be declared in the module, and rely on dead code elimination to not be linked in if not needed?
It might make sense to seal the Write trait; that'd allow later addition of requirements. (I'm not sure even the current requirements are sufficient.)
If code and RAM size matter a lot and hashing is rare, generalizing Crc
into a trait that's implemented by CrcWithTable
and CrcWithoutTable
may make sense (where the WithoutTable generates the entries at runtime, saving 2k of table space minus the size of the entry generation).
Having make_table
be const
is the ideal solution but it's quite difficult due to the current limitations of constant evaluation. There can't be loops, heap allocation, or mutable state in const fn
. However, there is active development in opening up constant evaluation to support these things.
I figure that tables for the common algorithms would just all be declared in the module, and rely on dead code elimination to not be linked in if not needed?
I think that makes the most sense.
If code and RAM size matter a lot and hashing is rare, generalizing Crc into a trait that's implemented by CrcWithTable and CrcWithoutTable may make sense (where the WithoutTable generates the entries at runtime, saving 2k of table space minus the size of the entry generation).
Wouldn't having Crc::new
be const
address this use case? If Crc::new
is used to declare a module-level const
, then the table is generated at compile time. If Crc::new
is used in function scope, then the table is generated at runtime.
Wouldn't having Crc::new be const address this use case?
I was rather thinking about not calculating the table at all (when RAM is a premium as well) and calculating the table's entries for each access. My point was not about implementing this now, but leaving such possibilities open by something like this:
pub trait Crc<W: Width> {
fn get_init() -> W;
fn get_entry(u8) -> W;
}
pub struct TableCrc<W: Width> {
algorithm: &'static Algorithm<W>,
table: [W; 256],
}
impl<W: Width> Crc<W> for TableCrc<W> {
fn get_init() -> W {
self.algorithm.init
}
fn get_entry(i: u8) -> W {
self.table[i]
}
}
pub struct Digest<'a, W: Width, C: Crc<W>> {
crc: &'a C,
value: W,
}
impl<'a, W: Width, C: Crc<W>> Digest<'a, W, C> {
fn new(crc: &'a impl Crc<W>) -> Self {
Digest { crc, crc.get_init() }
}
}
That's a bit hypothetical, though, so if the above would make things overly complicated, and at the same time doesn't allow using a CRC accelerator like the one in STM32s with the same interface (which would require going through a trait not at the Crc but at the Digest level). It's probably be better to go for a v2 as it is now rather than to fall into the second version pitfall here.
Just throwing my two cents in but I would love if the API functioned roughly the same as https://github.com/RustCrypto/hashes
I was going through documentation which shows to use 2.0
as the version but the last release is still on 1.8.1
, is there a plan to release these v2 changes?
With #55 merged, do we want to close out this one / track additional improvements in a separate issue?
Published 2.0.0 after rc period
Addresses a couple of different issues (https://github.com/mrhooray/crc-rs/pull/37, https://github.com/mrhooray/crc-rs/pull/46, https://github.com/mrhooray/crc-rs/issues/45, https://github.com/mrhooray/crc-rs/issues/40):
crc16
,crc32
, andcrc64
modulesThis represents a significant change in the API and internal structure of this library, but I believer the advantages are clear. Fully implementing these changes will take quite a bit of work. So, I wanted to get feedback before drafting a PR.