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
RevLine 
[128]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
[131]15#define ASSERT_ARGS(x) \
16 if ((x)) \
17 return CF_ERROR_BITWISE_INVALID_ARGS
[153]18
[128]19/**
20 * 비트열을 왼쪽으로 시프트
21 *
22 * \return 성공 시, CF_OK; 실패 시, 오류 코드
23 *
24 * \param in 시프트 할 비트열
25 * \param size 비트열 길이 (8의 배수)
26 * \param offset 시프트 할 수
[129]27 * \param out 시프트 결과
[128]28 */
29int
30CF_Bitwise_ShiftLeft (cf_byte * in,
31 size_t size,
[129]32 size_t offset,
33 cf_byte * out)
[128]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;
[153]40 size_t loop = byteSize - quota;
[128]41
[153]42 size_t idx = 0;
[128]43 size_t maskPos = 8 - remain;
[153]44 cf_byte mask = (cf_byte)(0xff << (8 - remain));
[128]45
[131]46 ASSERT_ARGS (!in || !out);
[128]47
48 out[0] = (cf_byte)(in[0 + quota] << remain);
49
[153]50 for (iter = 1 ; iter < loop ; iter++)
[128]51 {
[153]52 idx = iter + quota;
[128]53
[153]54 out[iter ] = (cf_byte)((in[idx] ) << remain);
55 out[iter - 1] |= (cf_byte)((in[idx] & mask) >> maskPos);
[128]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 시프트 할 수
[129]69 * \param out 시프트 결과
[128]70 */
71int
72CF_Bitwise_ShiftRight (cf_byte * in,
73 size_t size,
[129]74 size_t offset,
75 cf_byte * out)
[128]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;
[153]82 size_t loop = quota - 1;
[128]83
[153]84 size_t idx = 0;
[128]85 size_t maskPos = 8 - remain;
[153]86 cf_byte mask = (cf_byte)(0xff >> (8 - remain));
[128]87
[131]88 ASSERT_ARGS (!in || !out);
[128]89
90 out[byteSize - 1] = (cf_byte)(in[byteSize - 1 - quota] >> remain);
91
[153]92 for (iter = byteSize - 2 ; iter > loop ; iter--)
[128]93 {
[153]94 idx = iter - quota;
[128]95
[153]96 out[iter ] = (cf_byte)((in[idx] ) >> remain);
97 out[iter + 1] |= (cf_byte)((in[idx] & mask) << maskPos);
[128]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 로테이션 할 수
[129]111 * \param out 로테이션 결과
[128]112 */
113int
114CF_Bitwise_RotateLeft (cf_byte * in,
115 size_t size,
[129]116 size_t offset,
117 cf_byte * out)
[128]118{
[138]119 cf_byte * buf = NULL;
[128]120
[131]121 ASSERT_ARGS (!in || !out);
[128]122
[138]123 /* make buffer two times of size */
124 buf = (cf_byte *) calloc (size, 2);
125 if (!buf)
126 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
[128]127
[138]128 CF_Bitwise_ShiftLeft (in, size, offset, buf);
129 CF_Bitwise_ShiftRight (in, size, size - offset, buf + size);
[128]130
[138]131 CF_Bitwise_OR (buf, buf + size, size, out);
[128]132
[138]133 free (buf);
[128]134
[138]135 return CF_OK;
[128]136}
137
138/**
139 * 비트열을 오른쪽으로 로테이션
140 *
141 * \return 성공 시, CF_OK; 실패 시, 오류 코드
142 *
143 * \param in 로테이션 할 비트열
144 * \param size 비트열 길이 (8의 배수)
145 * \param offset 로테이션 할 수
[129]146 * \param out 로테이션 결과
[128]147 */
148int
149CF_Bitwise_RotateRight (cf_byte * in,
150 size_t size,
[129]151 size_t offset,
152 cf_byte * out)
[128]153{
[138]154 cf_byte * buf = NULL;
[128]155
[131]156 ASSERT_ARGS (!in || !out);
[128]157
[138]158 /* make buffer two times of size */
159 buf = (cf_byte *) calloc (size, 2);
160 if (!buf)
161 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
[128]162
[138]163 CF_Bitwise_ShiftRight (in, size, offset, buf);
164 CF_Bitwise_ShiftLeft (in, size, size - offset, buf + size);
[128]165
[138]166 CF_Bitwise_OR (buf, buf + size, size, out);
[128]167
[138]168 free (buf);
[128]169
[138]170 return CF_OK;
[128]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
[131]192 ASSERT_ARGS (!in1 || !in2 || !out);
[128]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
[131]219 ASSERT_ARGS (!in1 || !in2 || !out);
[128]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
[131]246 ASSERT_ARGS (!in1 || !in2 || !out);
[128]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.