해당 사이트의 알고리즘을 구현

// crc_ccitt.h #define _CRT_SECURE_NO_WARNINGS #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // 교재�� CRC16은 CRC16_CCITT 방정식을 이용한다. // x^16 + x^12 + x^5 + 1 // 이것을 16진��와 2진��로 변����면 아��와 같다. // 0x1021 (hex) <=> 0001 0000 0010 0001 (binary) // ��한 CRC16_CCITT�� INITIAL_VALUE는 0xFFFF이므로 이것을 사용��여 // CRC를 계산할 �� 있다. // 참조 사이트 : http://alaveiw.tistory.com/entry/crc32-%EC%BD%94%EB%93%9C static const char CRC_CCITT_POLYNOMIAL[] = "0001000000100001"; static const char INITIAL_VALUE[] = "1111111111111111"; void getDataCode(char *); void convertHexToBinary(char *, char *); void printBinaryDataCode(char *); void printHexDataCode(char *); void checkPaddingBit(char *); char* getRemainder(char *, size_t); void shift1BitLeft(char* remainder); void onXORCalc(char *); void getDataCode(char* hexDataCode) { printf("Data Code를 입력��세요(Input Type = Hexadecimal) : "); gets(hexDataCode); } void convertHexToBinary(char* hexDataCode, char* binaryDataCode) { size_t i = 0; const size_t numOfHexToBinary = 4; while (hexDataCode[i]) { switch (hexDataCode[i]) { case '0': strncat(binaryDataCode, "0000", numOfHexToBinary); break; case '1': strncat(binaryDataCode, "0001", numOfHexToBinary); break; case '2': strncat(binaryDataCode, "0010", numOfHexToBinary); break; case '3': strncat(binaryDataCode, "0011", numOfHexToBinary); break; case '4': strncat(binaryDataCode, "0100", numOfHexToBinary); break; case '5': strncat(binaryDataCode, "0101", numOfHexToBinary); break; case '6': strncat(binaryDataCode, "0110", numOfHexToBinary); break; case '7': strncat(binaryDataCode, "0111", numOfHexToBinary); break; case '8': strncat(binaryDataCode, "1000", numOfHexToBinary); break; case '9': strncat(binaryDataCode, "1001", numOfHexToBinary); break; case 'A': strncat(binaryDataCode, "1010", numOfHexToBinary); break; case 'B': strncat(binaryDataCode, "1011", numOfHexToBinary); break; case 'C': strncat(binaryDataCode, "1100", numOfHexToBinary); break; case 'D': strncat(binaryDataCode, "1101", numOfHexToBinary); break; case 'E': strncat(binaryDataCode, "1110", numOfHexToBinary); break; case 'F': strncat(binaryDataCode, "1111", numOfHexToBinary); break; case 'a': strncat(binaryDataCode, "1010", numOfHexToBinary); break; case 'b': strncat(binaryDataCode, "1011", numOfHexToBinary); break; case 'c': strncat(binaryDataCode, "1100", numOfHexToBinary); break; case 'd': strncat(binaryDataCode, "1101", numOfHexToBinary); break; case 'e': strncat(binaryDataCode, "1110", numOfHexToBinary); break; case 'f': strncat(binaryDataCode, "1111", numOfHexToBinary); break; } ++i; } checkPaddingBit(binaryDataCode); } void checkPaddingBit(char* binaryDataCode) { size_t i; size_t lengthOfData = strlen(binaryDataCode); const size_t numOfHexToBinary = 4; char* tempString = (char *)malloc(sizeof(char) * numOfHexToBinary); if (strlen(binaryDataCode) % 8 != 0) { strncpy(tempString, &binaryDataCode[lengthOfData - 4], numOfHexToBinary); tempString[4] = '\0'; // NULL Terminated for (i = 0; i < numOfHexToBinary; ++i) { binaryDataCode[lengthOfData - numOfHexToBinary + i] = '0'; } strncat(binaryDataCode, tempString, sizeof(tempString)); } } void printBinaryDataCode(char* binaryDataCode) { size_t i; printf("============================================================"); printf("==========\n"); for (i = 0; i < strlen(binaryDataCode); i += 4) { printf("%c%c%c%c ", binaryDataCode[i], binaryDataCode[i + 1], binaryDataCode[i + 2], binaryDataCode[i + 3]); } printf("\n============================================================"); printf("==========\n"); } void printHexDataCode(char* binaryData) { int i; long long int hexNumber = 0; int binaryDataLength = strlen(binaryData); char* hexData = (char *)malloc((size_t) (sizeof(char) * binaryDataLength * 0.25)); memset(hexData, 0, (size_t) (binaryDataLength * 0.25)); for (i = 0; i < binaryDataLength; ++i) { hexNumber += (long long) ((binaryData[binaryDataLength - i - 1] - 48) * pow(2.0, i)); } printf("============================================================"); printf("==========\n"); printf("0x%llX", hexNumber); printf("\n============================================================"); printf("==========\n"); } char* getRemainder(char* binaryDataCode, size_t dataCodeLength) { size_t i; char* remainder = (char *)malloc(sizeof(char) * 16); memset(remainder, 0, 16); strncpy(remainder, INITIAL_VALUE, sizeof(INITIAL_VALUE)); for (i = 0; i < dataCodeLength; ++i) { if ((remainder[0] == '1' && binaryDataCode[i] == '0') || (remainder[0] == '0' && binaryDataCode[i] == '1')) { shift1BitLeft(remainder); onXORCalc(remainder); } else { shift1BitLeft(remainder); } } return remainder; } void shift1BitLeft(char* remainder) { memmove(remainder, remainder + 1, strlen(remainder) - 1); memset(remainder + strlen(remainder) - 1, '0', 1); } void onXORCalc(char* remainder) { size_t i; for (i = 0; i < 16; ++i) { if ((remainder[i] == '1' && CRC_CCITT_POLYNOMIAL[i] == '0') || (remainder[i] == '0' && CRC_CCITT_POLYNOMIAL[i] == '1')) { remainder[i] = '1'; } else { remainder[i] = '0'; } } }

// crc_ccitt.c
#include "crc_ccitt.h"

int main() {  
  char hexDataCode[64] = {0, };
  char binaryDataCode[256] = {0, };

  char* remainder = "";
  char codeWord[256] = {0, };

  // get Data Code from User input
  getDataCode(hexDataCode);
  // 16진��로 입력된 Input 값을 2진��로 변��한다.
  convertHexToBinary(hexDataCode, binaryDataCode);

  printf("\n입력��신 Hex Data Code�� Binary Data Code는 다음과 같습니다.\n");
  printBinaryDataCode(binaryDataCode);
  printHexDataCode(binaryDataCode);

  // Shift와 XOR 연산을 이용��여 입력받은 Data Code�� CRC Code를 구한다.
  remainder = getRemainder(binaryDataCode, 
    strnlen(binaryDataCode, sizeof(binaryDataCode)));

  printf("\n입력��신 Data Code�� CRC Code는 다음과 같습니다.\n");
  printBinaryDataCode(remainder);
  printHexDataCode(remainder);

  printf("\nEncoding 시작...\n");
  // Code Word = Binary Data Code + Remainder
  strncat(codeWord, binaryDataCode, strlen(binaryDataCode));
  strncat(codeWord, remainder, strlen(remainder));
  printf("\n입력��신 Data Code�� Encoding 후 Code Word는 다음과 같습니다.\n");
  printBinaryDataCode(codeWord);
  printHexDataCode(codeWord);

  printf("\nDecoding 시작...\n");
  // Code Word를 다시 Polynomial로 ��눈 후 ��머지를 확인한다.
  // 이 때 ��머지가 0000 0000 0000 0000이면 전송된 Data가
  // Collapse ��지 않��다고 볼 �� 있다.
  memset(remainder, 0, strlen(remainder));
  // Code Word를 정해진 Polynomial(CRC_CCITT, 0x1021)��
  // Shift 및 XOR 연산을 통해 ��머지를 구한다.
  remainder = 
    getRemainder(codeWord, strnlen(codeWord, sizeof(codeWord)));
  printf("\n전송된 Code Word�� Decoding 후 Remainder는 다음과 같습니다.\n");
  printBinaryDataCode(remainder);
  printHexDataCode(remainder);
  return 0;
}