diff --git a/CRC.h b/CRC.h index 1aab83b..c19b61d 100644 --- a/CRC.h +++ b/CRC.h @@ -5,8 +5,8 @@ // Table 형식. // 모든 입력 값 256개 (0x00 ~ 0xFF) 에 대한 결과를 저장한 테이블. -// 기준값 : 0xED B8 83 20 -// 기준 비트 순서 : LSB -> MSB +// 기준값 : 0xED B8 83 20 (역방향 CRC Polynominal) +// 기준 비트 순서 : (Bit-reversed) Little Endian (LSB -> MSB) static const uint32_t crcTable[256] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, @@ -72,4 +72,26 @@ static const uint32_t crcTable[256] = { 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL -}; \ No newline at end of file +}; + +inline uint32_t getCRC32(const char* pData, size_t length) +{ + uint32_t crc = 0xFFFFFFFF; + + // 1. 입력 + for (size_t i = 0; i < length ; i++) + { + // Index 추출 + // 입력과 현재 CRC를 1 Byte 씩 XOR + (1의 보수처리) + uint8_t iTableIdx = (crc ^ pData[i]) & 0xFF; + + // 1 Byte Shift + crc = crc >> 8; + + // Table 과 XOR 계산 + crc = crc ^ crcTable[iTableIdx]; + } + + // 1의 보수처리 + return crc ^ 0xFFFFFFFF; +} \ No newline at end of file diff --git a/main.cpp b/main.cpp index 580a9f3..f09df6d 100644 --- a/main.cpp +++ b/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "ZipDefine.h" #include "CRC.h" @@ -10,7 +11,6 @@ #define OUTPUT_FILE_NAME "MyZip.zip" bool ZipArchiver(); -uint32_t getCRC32(const char* pData, size_t length); int main() { @@ -48,25 +48,22 @@ bool ZipArchiver() else { // 파일 크기 계산 - // seekg(offset, 목표점) - fileIn.seekg(0, ios::end); - streamsize fileInSize = fileIn.tellg(); - // beg == begin - fileIn.seekg(0, ios::beg); - // TODO : Buffering 으로 구현. 현재는 파일 통짜로 읽음. + fileIn.seekg(0, ios::end); // seekg(offset, 목표점) + streamsize fileInSize = fileIn.tellg(); + fileIn.seekg(0, ios::beg); // beg == begin + // 메모리 할당 - // TODO : 자동으로 free 되는 구조로 변경 - auto pFile = (char *)malloc(fileInSize); + vector fileInBuffer(fileInSize); + auto* pInBuffer = reinterpret_cast(fileInBuffer.data()); // Read - fileIn.read(pFile, fileInSize); + fileIn.read(pInBuffer, fileInSize); // ZIP 포맷 채워넣기 - // TODO : 여기있을 필요까진 없는듯. 코드 이관 필요 + // TODO : 클래스화 대상 { // Get CRC value - // TODO : 현재 streamsize 와 size_t 의 mismatch 존재. 해결필요.(long long <-> unsigned long long) - uint32_t myCRC = getCRC32(pFile, fileInSize); + uint32_t myCRC = getCRC32(pInBuffer, fileInSize); // Put PK Signature LFHeader.signature = PK_SIGNATURE_LF_HEADER; @@ -142,7 +139,7 @@ bool ZipArchiver() //fileOut.write(NOT_USED, LFHeader.LFHeader.lengthOfExtraField); // 2. File Data - fileOut.write(pFile, fileInSize); + fileOut.write(pInBuffer, fileInSize); // 3. CentralDirectory, file name (var) EOCDR.offsetCentralDir = static_cast(fileOut.tellp()); @@ -159,33 +156,8 @@ bool ZipArchiver() } // Free - free(pFile); + free(pInBuffer); } return iRet; -} - -uint32_t getCRC32(const char* pData, size_t length) -{ - uint32_t crc = 0xFFFFFFFF; - - // 1. 입력 - for (size_t i = 0; i < length ; i++) - { - // Index 추출 - // 입력과 현재 CRC를 1 Byte 씩 XOR + (1의 보수처리) - uint8_t iTableIdx = (crc ^ pData[i]) & 0xFF; - - // 1 Byte Shift - crc = crc >> 8; - - // Table 과 XOR 계산 - crc = crc ^ crcTable[iTableIdx]; - } - - // TODO : CRC 최적화 - // "_mm_crc32_u16" => MSVC 자체적으로 지원하는 최적화된 CRC 가 있는듯? - - // 1의 보수처리 - return crc ^ 0xFFFFFFFF; } \ No newline at end of file