source: libcf/trunk/src/cf_bitwise.c@ 153

Last change on this file since 153 was 153, checked in by cheese, 11 years ago

#1 fix bitwise simplify

File size: 5.0 KB
Line 
1/**
2 * \file cf_bitwise.c
3 *
4 * \author myusgun <myusgun@gmail.com>
5 * \author chevalier <achagun@gmail.com>
6 *
7 * \brief 비트 연산자 구현
8 */
9#include "cf_bitwise.h"
10#include "cf_error.h"
11
12#include <stdio.h>
13#include <stdlib.h>
14
15#define ASSERT_ARGS(x) \
16 if ((x)) \
17 return CF_ERROR_BITWISE_INVALID_ARGS
18
19/**
20 * 비트열을 왼쪽으로 시프트
21 *
22 * \return 성공 시, CF_OK; 실패 시, 오류 코드
23 *
24 * \param in 시프트 할 비트열
25 * \param size 비트열 길이 (8의 배수)
26 * \param offset 시프트 할 수
27 * \param out 시프트 결과
28 */
29int
30CF_Bitwise_ShiftLeft (cf_byte * in,
31 size_t size,
32 size_t offset,
33 cf_byte * out)
34{
35 size_t iter = 0;
36
37 size_t quota = offset / 8;
38 size_t remain = offset % 8;
39 size_t byteSize = size / 8;
40 size_t loop = byteSize - quota;
41
42 size_t idx = 0;
43 size_t maskPos = 8 - remain;
44 cf_byte mask = (cf_byte)(0xff << (8 - remain));
45
46 ASSERT_ARGS (!in || !out);
47
48 out[0] = (cf_byte)(in[0 + quota] << remain);
49
50 for (iter = 1 ; iter < loop ; iter++)
51 {
52 idx = iter + quota;
53
54 out[iter ] = (cf_byte)((in[idx] ) << remain);
55 out[iter - 1] |= (cf_byte)((in[idx] & mask) >> maskPos);
56 }
57
58 return CF_OK;
59}
60
61/**
62 * 비트열을 오른쪽으로 시프트
63 *
64 * \return 성공 시, CF_OK; 실패 시, 오류 코드
65 *
66 * \param in 시프트 할 비트열
67 * \param size 비트열 길이 (8의 배수)
68 * \param offset 시프트 할 수
69 * \param out 시프트 결과
70 */
71int
72CF_Bitwise_ShiftRight (cf_byte * in,
73 size_t size,
74 size_t offset,
75 cf_byte * out)
76{
77 size_t iter = 0;
78
79 size_t quota = offset / 8;
80 size_t remain = offset % 8;
81 size_t byteSize = size / 8;
82 size_t loop = quota - 1;
83
84 size_t idx = 0;
85 size_t maskPos = 8 - remain;
86 cf_byte mask = (cf_byte)(0xff >> (8 - remain));
87
88 ASSERT_ARGS (!in || !out);
89
90 out[byteSize - 1] = (cf_byte)(in[byteSize - 1 - quota] >> remain);
91
92 for (iter = byteSize - 2 ; iter > loop ; iter--)
93 {
94 idx = iter - quota;
95
96 out[iter ] = (cf_byte)((in[idx] ) >> remain);
97 out[iter + 1] |= (cf_byte)((in[idx] & mask) << maskPos);
98 }
99
100 return CF_OK;
101}
102
103/**
104 * 비트열을 왼쪽으로 로테이션
105 *
106 * \return 성공 시, CF_OK; 실패 시, 오류 코드
107 *
108 * \param in 로테이션 할 비트열
109 * \param size 비트열 길이 (8의 배수)
110 * \param offset 로테이션 할 수
111 * \param out 로테이션 결과
112 */
113int
114CF_Bitwise_RotateLeft (cf_byte * in,
115 size_t size,
116 size_t offset,
117 cf_byte * out)
118{
119 cf_byte * buf = NULL;
120
121 ASSERT_ARGS (!in || !out);
122
123 /* make buffer two times of size */
124 buf = (cf_byte *) calloc (size, 2);
125 if (!buf)
126 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
127
128 CF_Bitwise_ShiftLeft (in, size, offset, buf);
129 CF_Bitwise_ShiftRight (in, size, size - offset, buf + size);
130
131 CF_Bitwise_OR (buf, buf + size, size, out);
132
133 free (buf);
134
135 return CF_OK;
136}
137
138/**
139 * 비트열을 오른쪽으로 로테이션
140 *
141 * \return 성공 시, CF_OK; 실패 시, 오류 코드
142 *
143 * \param in 로테이션 할 비트열
144 * \param size 비트열 길이 (8의 배수)
145 * \param offset 로테이션 할 수
146 * \param out 로테이션 결과
147 */
148int
149CF_Bitwise_RotateRight (cf_byte * in,
150 size_t size,
151 size_t offset,
152 cf_byte * out)
153{
154 cf_byte * buf = NULL;
155
156 ASSERT_ARGS (!in || !out);
157
158 /* make buffer two times of size */
159 buf = (cf_byte *) calloc (size, 2);
160 if (!buf)
161 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
162
163 CF_Bitwise_ShiftRight (in, size, offset, buf);
164 CF_Bitwise_ShiftLeft (in, size, size - offset, buf + size);
165
166 CF_Bitwise_OR (buf, buf + size, size, out);
167
168 free (buf);
169
170 return CF_OK;
171}
172
173/**
174 * 두 비트열의 AND
175 *
176 * \return 성공 시, CF_OK; 실패 시, 오류 코드
177 *
178 * \param in1 입력 비트열 1
179 * \param in2 입력 비트열 2
180 * \param size 비트열 길이 (8의 배수)
181 * \param out 두 비트열의 AND 결과
182 */
183int
184CF_Bitwise_AND (cf_byte * in1,
185 cf_byte * in2,
186 size_t size,
187 cf_byte * out)
188{
189 size_t iter = 0;
190 size_t quota = size / 8;
191
192 ASSERT_ARGS (!in1 || !in2 || !out);
193
194 for (iter = 0 ; iter < quota ; iter++)
195 out[iter] = in1[iter] & in2[iter];
196
197 return 0;
198}
199
200/**
201 * 두 비트열의 OR
202 *
203 * \return 성공 시, CF_OK; 실패 시, 오류 코드
204 *
205 * \param in1 입력 비트열 1
206 * \param in2 입력 비트열 2
207 * \param size 비트열 길이 (8의 배수)
208 * \param out 두 비트열의 OR 결과
209 */
210int
211CF_Bitwise_OR (cf_byte * in1,
212 cf_byte * in2,
213 size_t size,
214 cf_byte * out)
215{
216 size_t iter = 0;
217 size_t quota = size / 8;
218
219 ASSERT_ARGS (!in1 || !in2 || !out);
220
221 for (iter = 0 ; iter < quota ; iter++)
222 out[iter] = in1[iter] | in2[iter];
223
224 return 0;
225}
226
227/**
228 * 두 비트열의 XOR
229 *
230 * \return 성공 시, CF_OK; 실패 시, 오류 코드
231 *
232 * \param in1 입력 비트열 1
233 * \param in2 입력 비트열 2
234 * \param size 비트열 길이 (8의 배수)
235 * \param out 두 비트열의 XOR 결과
236 */
237int
238CF_Bitwise_XOR (cf_byte * in1,
239 cf_byte * in2,
240 size_t size,
241 cf_byte * out)
242{
243 size_t iter = 0;
244 size_t quota = size / 8;
245
246 ASSERT_ARGS (!in1 || !in2 || !out);
247
248 for (iter = 0 ; iter < quota ; iter++)
249 out[iter] = in1[iter] ^ in2[iter];
250
251 return 0;
252}
Note: See TracBrowser for help on using the repository browser.