/src/sleuthkit/tsk/base/crc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | |
3 | | Code taken and modified from: |
4 | | A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS |
5 | | |
6 | | Where the following copyright appears: |
7 | | |
8 | | Status : Copyright (C) Ross Williams, 1993. However, permission is |
9 | | granted to make and distribute verbatim copies of this |
10 | | document provided that this information block and copyright |
11 | | notice is included. Also, the C code modules included |
12 | | in this document are fully public domain. |
13 | | */ |
14 | | |
15 | | /******************************************************************************/ |
16 | | /* Start of crcmodel.c */ |
17 | | /******************************************************************************/ |
18 | | /* */ |
19 | | /* Author : Ross Williams (ross@guest.adelaide.edu.au.). */ |
20 | | /* Date : 3 June 1993. */ |
21 | | /* Status : Public domain. */ |
22 | | /* */ |
23 | | /* Description : This is the implementation (.c) file for the reference */ |
24 | | /* implementation of the Rocksoft^tm Model CRC Algorithm. For more */ |
25 | | /* information on the Rocksoft^tm Model CRC Algorithm, see the document */ |
26 | | /* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */ |
27 | | /* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */ |
28 | | /* "ftp.adelaide.edu.au/pub/rocksoft". */ |
29 | | /* */ |
30 | | /* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */ |
31 | | /* */ |
32 | | /******************************************************************************/ |
33 | | /* */ |
34 | | /* Implementation Notes */ |
35 | | /* -------------------- */ |
36 | | /* To avoid inconsistencies, the specification of each function is not echoed */ |
37 | | /* here. See the header file for a description of these functions. */ |
38 | | /* This package is light on checking because I want to keep it short and */ |
39 | | /* simple and portable (i.e. it would be too messy to distribute my entire */ |
40 | | /* C culture (e.g. assertions package) with this package. */ |
41 | | /* */ |
42 | | /******************************************************************************/ |
43 | | |
44 | | #include "crc.h" |
45 | | #include <stdio.h> |
46 | | |
47 | | #ifndef _MSC_VER |
48 | | #include <stdint.h> |
49 | | #endif |
50 | | /******************************************************************************/ |
51 | | |
52 | | /* The following definitions make the code more readable. */ |
53 | | |
54 | 0 | #define BITMASK(X) (1L << (X)) |
55 | | #define MASK32 0xFFFFFFFFL |
56 | | #define LOCAL static |
57 | | |
58 | | /******************************************************************************/ |
59 | | |
60 | | LOCAL ulong reflect P_((ulong v,int b)); |
61 | | LOCAL ulong reflect (ulong v,int b) |
62 | | /* Returns the value v with the bottom b [0,32] bits reflected. */ |
63 | | /* Example: reflect(0x3e23L,3) == 0x3e26 */ |
64 | 0 | { |
65 | 0 | int i; |
66 | 0 | ulong t = v; |
67 | 0 | for (i=0; i<b; i++) |
68 | 0 | { |
69 | 0 | if (t & 1L) |
70 | 0 | v|= BITMASK((b-1)-i); |
71 | 0 | else |
72 | 0 | v&= ~BITMASK((b-1)-i); |
73 | 0 | t>>=1; |
74 | 0 | } |
75 | 0 | return v; |
76 | 0 | } |
77 | | |
78 | | /******************************************************************************/ |
79 | | |
80 | | LOCAL ulong widmask P_((p_cm_t)); |
81 | | LOCAL ulong widmask (p_cm_t p_cm) |
82 | | /* Returns a longword whose value is (2^p_cm->cm_width)-1. */ |
83 | | /* The trick is to do this portably (e.g. without doing <<32). */ |
84 | 0 | { |
85 | 0 | return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L; |
86 | 0 | } |
87 | | |
88 | | /******************************************************************************/ |
89 | | |
90 | | void cm_ini (p_cm_t p_cm) |
91 | 0 | { |
92 | 0 | p_cm->cm_reg = p_cm->cm_init; |
93 | 0 | } |
94 | | |
95 | | /******************************************************************************/ |
96 | | |
97 | | void cm_nxt (p_cm_t p_cm,int ch) |
98 | 0 | { |
99 | 0 | int i; |
100 | 0 | ulong uch = (ulong) ch; |
101 | 0 | ulong topbit = BITMASK(p_cm->cm_width-1); |
102 | | |
103 | |
|
104 | 0 | if (p_cm->cm_refin) uch = reflect(uch,8); |
105 | 0 | p_cm->cm_reg ^= (uch << (p_cm->cm_width-8)); |
106 | 0 | for (i=0; i<8; i++) |
107 | 0 | { |
108 | 0 | if (p_cm->cm_reg & topbit) |
109 | 0 | p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly; |
110 | 0 | else |
111 | 0 | p_cm->cm_reg <<= 1; |
112 | 0 | p_cm->cm_reg &= widmask(p_cm); |
113 | 0 | } |
114 | 0 | } |
115 | | |
116 | | /******************************************************************************/ |
117 | | |
118 | | void cm_blk (p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len) |
119 | 0 | { |
120 | 0 | while (blk_len--) cm_nxt(p_cm,*blk_adr++); |
121 | 0 | } |
122 | | |
123 | | /******************************************************************************/ |
124 | | |
125 | | ulong cm_crc (p_cm_t p_cm) |
126 | 0 | { |
127 | 0 | if (p_cm->cm_refot) |
128 | 0 | return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width); |
129 | 0 | else |
130 | 0 | return p_cm->cm_xorot ^ p_cm->cm_reg; |
131 | 0 | } |
132 | | |
133 | | |
134 | | /******************************************************************************/ |
135 | | /* End of crcmodel.c */ |
136 | | /******************************************************************************/ |
137 | | |
138 | | void crc16(p_cm_t crc_context, unsigned char const *buff, unsigned int size) |
139 | 0 | { |
140 | 0 | while(size > 0) |
141 | 0 | { |
142 | 0 | cm_nxt(crc_context, *buff++); |
143 | 0 | size--; |
144 | 0 | } |
145 | 0 | } |
146 | | |
147 | | |
148 | | #ifdef TEST_CRC |
149 | | |
150 | | main() |
151 | | { |
152 | | cm_t TestCRC; |
153 | | |
154 | | TestCRC.cm_width = 16; |
155 | | TestCRC.cm_poly = 0x8005L; |
156 | | TestCRC.cm_init = 0x0000; |
157 | | // TestCRC.cm_init = 0xFFFF; |
158 | | TestCRC.cm_refin = TRUE; |
159 | | TestCRC.cm_refot = TRUE; |
160 | | TestCRC.cm_xorot = 0x0000; |
161 | | // TestCRC.cm_xorot = 0xFFFF; |
162 | | |
163 | | cm_ini(&TestCRC); |
164 | | char TestString[]="123456789"; |
165 | | char *finger = NULL; |
166 | | int i = 0; |
167 | | for(i = 0; i <strlen(TestString); i++) |
168 | | { |
169 | | finger = &TestString[i]; |
170 | | printf("%c-", *finger); |
171 | | cm_nxt(&TestCRC, *finger); |
172 | | } |
173 | | printf("\n"); |
174 | | printf("crc: 0x%04X\n", TestCRC.cm_reg); |
175 | | printf("crc: 0x%04X\n", cm_crc(&TestCRC)); |
176 | | |
177 | | } |
178 | | |
179 | | #endif |