~vcs-imports/busybox/trunk

« back to all changes in this revision

Viewing changes to libbb/crc32.c

  • Committer: Eric Andersen
  • Date: 1999-11-24 09:04:33 UTC
  • Revision ID: git-v1:b99df0fd65abe3245fa2d04115326100847f865e
First draft

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* vi: set sw=4 ts=4: */
2
 
/*
3
 
 * CRC32 table fill function
4
 
 * Copyright (C) 2006 by Rob Sullivan <cogito.ergo.cogito@gmail.com>
5
 
 * (I can't really claim much credit however, as the algorithm is
6
 
 * very well-known)
7
 
 *
8
 
 * The following function creates a CRC32 table depending on whether
9
 
 * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is
10
 
 * required. Admittedly, there are other CRC32 polynomials floating
11
 
 * around, but Busybox doesn't use them.
12
 
 *
13
 
 * endian = 1: big-endian
14
 
 * endian = 0: little-endian
15
 
 *
16
 
 * Licensed under GPLv2, see file LICENSE in this source tree.
17
 
 */
18
 
#include "libbb.h"
19
 
 
20
 
uint32_t *global_crc32_table;
21
 
 
22
 
uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian)
23
 
{
24
 
        uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320;
25
 
        uint32_t c;
26
 
        unsigned i, j;
27
 
 
28
 
        if (!crc_table)
29
 
                crc_table = xmalloc(256 * sizeof(uint32_t));
30
 
 
31
 
        for (i = 0; i < 256; i++) {
32
 
                c = endian ? (i << 24) : i;
33
 
                for (j = 8; j; j--) {
34
 
                        if (endian)
35
 
                                c = (c&0x80000000) ? ((c << 1) ^ polynomial) : (c << 1);
36
 
                        else
37
 
                                c = (c&1) ? ((c >> 1) ^ polynomial) : (c >> 1);
38
 
                }
39
 
                *crc_table++ = c;
40
 
        }
41
 
 
42
 
        return crc_table - 256;
43
 
}
44
 
/* Common uses: */
45
 
uint32_t* FAST_FUNC crc32_new_table_le(void)
46
 
{
47
 
        return crc32_filltable(NULL, 0);
48
 
}
49
 
uint32_t* FAST_FUNC global_crc32_new_table_le(void)
50
 
{
51
 
        global_crc32_table = crc32_new_table_le();
52
 
        return global_crc32_table;
53
 
}
54
 
 
55
 
uint32_t FAST_FUNC crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table)
56
 
{
57
 
        const void *end = (uint8_t*)buf + len;
58
 
 
59
 
        while (buf != end) {
60
 
                val = (val << 8) ^ crc_table[(val >> 24) ^ *(uint8_t*)buf];
61
 
                buf = (uint8_t*)buf + 1;
62
 
        }
63
 
        return val;
64
 
}
65
 
 
66
 
uint32_t FAST_FUNC crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table)
67
 
{
68
 
        const void *end = (uint8_t*)buf + len;
69
 
 
70
 
        while (buf != end) {
71
 
                val = crc_table[(uint8_t)val ^ *(uint8_t*)buf] ^ (val >> 8);
72
 
                buf = (uint8_t*)buf + 1;
73
 
        }
74
 
        return val;
75
 
}