/** * \file cf_bitwise.c * * \author myusgun * \author chevalier * * \brief 비트 연산자 구현 */ #include "cf_bitwise.h" #include "cf_error.h" #include #include /** * 비트열을 왼쪽으로 시프트 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 시프트 할 비트열 * \param out 시프트 결과 * \param size 비트열 길이 (8의 배수) * \param offset 시프트 할 수 */ int CF_Bitwise_ShiftLeft (cf_byte * in, cf_byte * out, size_t size, size_t offset) { size_t iter = 0; size_t quota = offset / 8; size_t remain = offset % 8; size_t byteSize = size / 8; size_t maskPos = 8 - remain; cf_byte mask = 0; cf_byte buf = 0; if (!in || !out) return CF_ERROR_BITWISE_INVALID_ARGS; for (iter = 0 ; iter < remain ; iter++) mask |= (cf_byte)(0x80 >> iter); out[0] = (cf_byte)(in[0 + quota] << remain); for (iter = 1 ; iter < byteSize - quota ; iter++) { buf = in[iter + quota] & mask; out[iter ] = (cf_byte)(in[iter + quota] << remain); out[iter - 1] |= (cf_byte)(buf >> maskPos); } return CF_OK; } /** * 비트열을 오른쪽으로 시프트 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 시프트 할 비트열 * \param out 시프트 결과 * \param size 비트열 길이 (8의 배수) * \param offset 시프트 할 수 */ int CF_Bitwise_ShiftRight (cf_byte * in, cf_byte * out, size_t size, size_t offset) { size_t iter = 0; size_t quota = offset / 8; size_t remain = offset % 8; size_t byteSize = size / 8; size_t maskPos = 8 - remain; cf_byte mask = 0; cf_byte buf = 0; if (!in || !out) return CF_ERROR_BITWISE_INVALID_ARGS; for (iter = 0 ; iter < remain ; iter++) mask |= (cf_byte)(0x01 << iter); out[byteSize - 1] = (cf_byte)(in[byteSize - 1 - quota] >> remain); for (iter = byteSize - 2 ; iter > quota - 1 ; iter--) { buf = in[iter - quota] & mask; out[iter ] = (cf_byte)(in[iter - quota] >> remain); out[iter + 1] |= (cf_byte)(buf << maskPos); } return CF_OK; } /** * 비트열을 왼쪽으로 로테이션 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 로테이션 할 비트열 * \param out 로테이션 결과 * \param size 비트열 길이 (8의 배수) * \param offset 로테이션 할 수 */ int CF_Bitwise_RotateLeft (cf_byte * in, cf_byte * out, size_t size, size_t offset) { int result = 0; cf_byte * buf1 = NULL; cf_byte * buf2 = NULL; if (!in || !out) return CF_ERROR_BITWISE_INVALID_ARGS; buf1 = (cf_byte *) calloc (size, 1); buf2 = (cf_byte *) calloc (size, 1); if (!buf1 || !buf2) result = CF_ERROR_BITWISE_ALLOCATE_BUFFER; else { CF_Bitwise_ShiftLeft (in, buf1, size, offset); CF_Bitwise_ShiftRight (in, buf2, size, size - offset); CF_Bitwise_OR (buf1, buf2, size, out); } if (buf1) free (buf1); if (buf2) free (buf2); return result; } /** * 비트열을 오른쪽으로 로테이션 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param in 로테이션 할 비트열 * \param out 로테이션 결과 * \param size 비트열 길이 (8의 배수) * \param offset 로테이션 할 수 */ int CF_Bitwise_RotateRight (cf_byte * in, cf_byte * out, size_t size, size_t offset) { int result = 0; cf_byte * buf1 = NULL; cf_byte * buf2 = NULL; if (!in || !out) return CF_ERROR_BITWISE_INVALID_ARGS; buf1 = (cf_byte *) calloc (size, 1); buf2 = (cf_byte *) calloc (size, 1); if (!buf1 || !buf2) result = CF_ERROR_BITWISE_ALLOCATE_BUFFER; else { CF_Bitwise_ShiftRight (in, buf1, size, offset); CF_Bitwise_ShiftLeft (in, buf2, size, size - offset); CF_Bitwise_OR (buf1, buf2, size, out); } if (buf1) free (buf1); if (buf2) free (buf2); return result; } /** * 두 비트열의 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; if (!in1 || !in2) return CF_ERROR_BITWISE_INVALID_ARGS; 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; if (!in1 || !in2) return CF_ERROR_BITWISE_INVALID_ARGS; 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; if (!in1 || !in2) return CF_ERROR_BITWISE_INVALID_ARGS; for (iter = 0 ; iter < quota ; iter++) out[iter] = in1[iter] ^ in2[iter]; return 0; }