mirror of
https://github.com/aaru-dps/Aaru.Checksums.Native.git
synced 2025-12-16 11:14:29 +00:00
Change CRC algorithms to use slicing.
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -35,11 +34,47 @@ AARU_EXPORT crc16_ccitt_ctx* AARU_CALL crc16_ccitt_init(void)
|
||||
|
||||
AARU_EXPORT int AARU_CALL crc16_ccitt_update(crc16_ccitt_ctx* ctx, const uint8_t* data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
// Unroll according to Intel slicing by uint8_t
|
||||
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
// http://sourceforge.net/projects/slicing-by-8/
|
||||
|
||||
if(!ctx || !data) return -1;
|
||||
|
||||
for(i = 0; i < len; i++) ctx->crc = crc16_ccitt_table[(ctx->crc >> 8) ^ data[i]] ^ (ctx->crc << 8);
|
||||
uint16_t crc;
|
||||
const uint8_t* current_char = (const uint8_t*)data;
|
||||
const size_t unroll = 4;
|
||||
const size_t bytes_at_once = 8 * unroll;
|
||||
uintptr_t unaligned_length = (4 - (((uintptr_t)current_char) & 3)) & 3;
|
||||
|
||||
crc = ctx->crc;
|
||||
|
||||
while((len != 0) && (unaligned_length != 0))
|
||||
{
|
||||
crc = (crc << 8) ^ crc16_ccitt_table[0][(crc >> 8) ^ *current_char++];
|
||||
len--;
|
||||
unaligned_length--;
|
||||
}
|
||||
|
||||
while(len >= bytes_at_once)
|
||||
{
|
||||
size_t unrolling;
|
||||
for(unrolling = 0; unrolling < unroll; unrolling++)
|
||||
{
|
||||
crc = crc16_ccitt_table[7][current_char[0] ^ (crc >> 8)] ^
|
||||
crc16_ccitt_table[6][current_char[1] ^ (crc & 0xFF)] ^ crc16_ccitt_table[5][current_char[2]] ^
|
||||
crc16_ccitt_table[4][current_char[3]] ^ crc16_ccitt_table[3][current_char[4]] ^
|
||||
crc16_ccitt_table[2][current_char[5]] ^ crc16_ccitt_table[1][current_char[6]] ^
|
||||
crc16_ccitt_table[0][current_char[7]];
|
||||
|
||||
current_char += 8;
|
||||
}
|
||||
|
||||
len -= bytes_at_once;
|
||||
}
|
||||
|
||||
while(len-- != 0) crc = (crc << 8) ^ crc16_ccitt_table[0][(crc >> 8) ^ *current_char++];
|
||||
|
||||
ctx->crc = crc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user