/** * \file cf_bitwise.c * * \author myusgun * \author chevalier * * \brief 비트 연산자 구현 */ #include "cf_bitwise.h" #include "cf_error.h" #include #include #define ASSERT_ARGS(x) \ if ((x)) \ return CF_ERROR_BITWISE_INVALID_ARGS /** * 비트열을 왼쪽으로 시프트 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 시프트 할 비트열 * \param size 비트열 길이 (8의 배수) * \param offset 시프트 할 수 * \param out 시프트 결과 */ int CF_Bitwise_ShiftLeft (cf_byte * in, size_t size, size_t offset, cf_byte * out) { size_t iter = 0; size_t quota = offset / 8; size_t remain = offset % 8; size_t byteSize = size / 8; size_t loop = byteSize - quota; size_t idx = 0; size_t maskPos = 8 - remain; cf_byte mask = (cf_byte)(0xff << (8 - remain)); ASSERT_ARGS (!in || !out); out[0] = (cf_byte)(in[0 + quota] << remain); for (iter = 1 ; iter < loop ; iter++) { idx = iter + quota; out[iter ] = (cf_byte)((in[idx] ) << remain); out[iter - 1] |= (cf_byte)((in[idx] & mask) >> maskPos); } return CF_OK; } /** * 비트열을 오른쪽으로 시프트 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 시프트 할 비트열 * \param size 비트열 길이 (8의 배수) * \param offset 시프트 할 수 * \param out 시프트 결과 */ int CF_Bitwise_ShiftRight (cf_byte * in, size_t size, size_t offset, cf_byte * out) { size_t iter = 0; size_t quota = offset / 8; size_t remain = offset % 8; size_t byteSize = size / 8; size_t loop = quota - 1; size_t idx = 0; size_t maskPos = 8 - remain; cf_byte mask = (cf_byte)(0xff >> (8 - remain)); ASSERT_ARGS (!in || !out); out[byteSize - 1] = (cf_byte)(in[byteSize - 1 - quota] >> remain); for (iter = byteSize - 2 ; iter > loop ; iter--) { idx = iter - quota; out[iter ] = (cf_byte)((in[idx] ) >> remain); out[iter + 1] |= (cf_byte)((in[idx] & mask) << maskPos); } return CF_OK; } /** * 비트열을 왼쪽으로 로테이션 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 로테이션 할 비트열 * \param size 비트열 길이 (8의 배수) * \param offset 로테이션 할 수 * \param out 로테이션 결과 */ int CF_Bitwise_RotateLeft (cf_byte * in, size_t size, size_t offset, cf_byte * out) { cf_byte * buf = NULL; ASSERT_ARGS (!in || !out); /* make buffer two times of size */ buf = (cf_byte *) calloc (size, 2); if (!buf) return CF_ERROR_BITWISE_ALLOCATE_BUFFER; CF_Bitwise_ShiftLeft (in, size, offset, buf); CF_Bitwise_ShiftRight (in, size, size - offset, buf + size); CF_Bitwise_OR (buf, buf + size, size, out); free (buf); return CF_OK; } /** * 비트열을 오른쪽으로 로테이션 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 로테이션 할 비트열 * \param size 비트열 길이 (8의 배수) * \param offset 로테이션 할 수 * \param out 로테이션 결과 */ int CF_Bitwise_RotateRight (cf_byte * in, size_t size, size_t offset, cf_byte * out) { cf_byte * buf = NULL; ASSERT_ARGS (!in || !out); /* make buffer two times of size */ buf = (cf_byte *) calloc (size, 2); if (!buf) return CF_ERROR_BITWISE_ALLOCATE_BUFFER; CF_Bitwise_ShiftRight (in, size, offset, buf); CF_Bitwise_ShiftLeft (in, size, size - offset, buf + size); CF_Bitwise_OR (buf, buf + size, size, out); free (buf); return CF_OK; } /** * 두 비트열의 AND * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in1 입력 비트열 1 * \param in2 입력 비트열 2 * \param size 비트열 길이 (8의 배수) * \param out 두 비트열의 AND 결과 */ int CF_Bitwise_AND (cf_byte * in1, cf_byte * in2, size_t size, cf_byte * out) { size_t iter = 0; size_t quota = size / 8; ASSERT_ARGS (!in1 || !in2 || !out); for (iter = 0 ; iter < quota ; iter++) out[iter] = in1[iter] & in2[iter]; return 0; } /** * 두 비트열의 OR * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in1 입력 비트열 1 * \param in2 입력 비트열 2 * \param size 비트열 길이 (8의 배수) * \param out 두 비트열의 OR 결과 */ int CF_Bitwise_OR (cf_byte * in1, cf_byte * in2, size_t size, cf_byte * out) { size_t iter = 0; size_t quota = size / 8; ASSERT_ARGS (!in1 || !in2 || !out); for (iter = 0 ; iter < quota ; iter++) out[iter] = in1[iter] | in2[iter]; return 0; } /** * 두 비트열의 XOR * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in1 입력 비트열 1 * \param in2 입력 비트열 2 * \param size 비트열 길이 (8의 배수) * \param out 두 비트열의 XOR 결과 */ int CF_Bitwise_XOR (cf_byte * in1, cf_byte * in2, size_t size, cf_byte * out) { size_t iter = 0; size_t quota = size / 8; ASSERT_ARGS (!in1 || !in2 || !out); for (iter = 0 ; iter < quota ; iter++) out[iter] = in1[iter] ^ in2[iter]; return 0; }