diff --git a/src/Helper/FileListHelper.cpp b/src/Helper/FileListHelper.cpp index 4403d2d..ba1a813 100644 --- a/src/Helper/FileListHelper.cpp +++ b/src/Helper/FileListHelper.cpp @@ -73,6 +73,46 @@ std::vector FileListHelper::getFileList(const std::string& aPath) return result; } +std::string FileListHelper::getCEMeasuredFileFromHJData(const std::string& aPath) +{ + std::string result; + std::string path = fixPathSlash(aPath); + std::string filter = path + "/CEMeasured*.bin"; +#ifdef _WIN32 + if(_access(path.c_str(), 0) == -1) + { + return std::string(); + } + _finddatai64_t file; + long long HANDLE = _findfirst64(filter.c_str(),&file); + long long f = HANDLE; + while (f != -1) + { + result = path+"/"+file.name; + break; + } + _findclose(HANDLE); +#else + DIR* dir = opendir(path.c_str()); + if (dir == nullptr) + { + return std::string(); + } + dirent* file; + while((file = readdir(dir)) != nullptr) + { + if(std::regex_match(file->d_name,std::regex("CEMeasured.*bin"))) + { + result = path+"/"+file->d_name; + break; + } + } + closedir(dir); +#endif + + return result; +} + std::string FileListHelper::fixPathSlash(const std::string& aPath) { std::string result = aPath; diff --git a/src/Helper/FileListHelper.h b/src/Helper/FileListHelper.h index cac04bf..f38517b 100644 --- a/src/Helper/FileListHelper.h +++ b/src/Helper/FileListHelper.h @@ -9,6 +9,7 @@ class FileListHelper public: static std::vector getFileList(const std::string& aPath); static std::string fixPathSlash(const std::string& aPath); + static std::string getCEMeasuredFileFromHJData(const std::string& aPath); FileListHelper() = delete; }; diff --git a/src/Md5/Md5.cpp b/src/Md5/Md5.cpp new file mode 100644 index 0000000..6d1eae9 --- /dev/null +++ b/src/Md5/Md5.cpp @@ -0,0 +1,182 @@ +#include "md5.h" +#include + +unsigned char PADDING[] = +{ + 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +void MD5Init(MD5_CTX *context) +{ + context->count[0] = 0; + context->count[1] = 0; + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; +} + +void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen) +{ + unsigned int i = 0; + unsigned int index = 0; + unsigned int partlen = 0; + + index = (context->count[0] >> 3) & 0x3F; + partlen = 64 - index; + context->count[0] += inputlen << 3; + + if(context->count[0] < (inputlen << 3)) + context->count[1]++; + context->count[1] += inputlen >> 29; + + if(inputlen >= partlen) + { + memcpy(&context->buffer[index], input,partlen); + MD5Transform(context->state, context->buffer); + + for(i = partlen; i+64 <= inputlen; i+=64) + MD5Transform(context->state, &input[i]); + + index = 0; + } + else + { + i = 0; + } + memcpy(&context->buffer[index], &input[i], inputlen-i); +} + +void MD5Final(MD5_CTX *context, unsigned char digest[16]) +{ + unsigned int index = 0,padlen = 0; + unsigned char bits[8]; + + index = (context->count[0] >> 3) & 0x3F; + padlen = (index < 56)?(56-index):(120-index); + MD5Encode(bits, context->count, 8); + MD5Update(context, PADDING, padlen); + MD5Update(context, bits, 8); + MD5Encode(digest, context->state, 16); +} + +void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) +{ + unsigned int i = 0; + unsigned int j = 0; + + while(j < len) + { + output[j] = input[i] & 0xFF; + output[j+1] = (input[i] >> 8) & 0xFF; + output[j+2] = (input[i] >> 16) & 0xFF; + output[j+3] = (input[i] >> 24) & 0xFF; + i++; + j += 4; + } +} + +void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len) +{ + unsigned int i = 0; + unsigned int j = 0; + + while(j < len) + { + output[i] = (input[j]) | + (input[j+1] << 8) | + (input[j+2] << 16) | + (input[j+3] << 24); + i++; + j += 4; + } +} + +void MD5Transform(unsigned int state[4], unsigned char block[64]) +{ + unsigned int a = state[0]; + unsigned int b = state[1]; + unsigned int c = state[2]; + unsigned int d = state[3]; + unsigned int x[64]; + + MD5Decode(x,block,64); + + FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ + FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ + FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ + FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ + FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ + FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ + FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ + FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ + FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ + FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ + FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ + FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ + FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ + FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ + FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ + FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */ + GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */ + GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ + GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */ + GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */ + GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */ + GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ + GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */ + GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */ + GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ + GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */ + GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */ + GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ + GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */ + GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */ + GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */ + HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */ + HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ + HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ + HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */ + HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */ + HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */ + HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ + HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ + HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */ + HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */ + HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */ + HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */ + HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ + HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ + HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */ + II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */ + II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ + II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */ + II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ + II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */ + II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ + II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */ + II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */ + II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ + II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */ + II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ + II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */ + II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ + II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */ + II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} \ No newline at end of file diff --git a/src/Md5/Md5.h b/src/Md5/Md5.h new file mode 100644 index 0000000..5487a6f --- /dev/null +++ b/src/Md5/Md5.h @@ -0,0 +1,49 @@ +#ifndef MD5_H +#define MD5_H + +typedef struct +{ + unsigned int count[2]; + unsigned int state[4]; + unsigned char buffer[64]; +} MD5_CTX; + + +#define F(x,y,z) ((x & y) | (~x & z)) +#define G(x,y,z) ((x & z) | (y & ~z)) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y ^ (x | ~z)) +#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) + +#define FF(a,b,c,d,x,s,ac) \ +{ \ + a += F(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define GG(a,b,c,d,x,s,ac) \ +{ \ + a += G(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define HH(a,b,c,d,x,s,ac) \ +{ \ + a += H(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define II(a,b,c,d,x,s,ac) \ +{ \ + a += I(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +void MD5Init(MD5_CTX *context); +void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen); +void MD5Final(MD5_CTX *context, unsigned char digest[16]); +void MD5Transform(unsigned int state[4], unsigned char block[64]); +void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len); +void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len); + +#endif \ No newline at end of file diff --git a/src/Parser.cpp b/src/Parser.cpp index e89aaf6..711a9a0 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -99,3 +99,13 @@ TemperatureData Parser::getTemperatureData() { return mPrivate->getTemperatureData(); } + +bool Parser::hasCEMeasured() +{ + return mPrivate->hasCEMeasured(); +} + +bool Parser::verifyHashValue() +{ + return mPrivate->verifyHashValue(); +} diff --git a/src/Parser.h b/src/Parser.h index 47378e6..090f4cf 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -42,6 +42,8 @@ public: MovementData getMovementData(); PatientData getPatientData(); TemperatureData getTemperatureData(); + bool hasCEMeasured(); + bool verifyHashValue(); Parser(const Parser& aParser); std::shared_ptr clone(); diff --git a/src/Parser.pro b/src/Parser.pro index 0807da7..3c5f606 100644 --- a/src/Parser.pro +++ b/src/Parser.pro @@ -57,7 +57,8 @@ SOURCES += \ Helper/MatlabHelper.cpp \ Data/ConfigHeader.cpp \ DataReader/ConfigHeaderReader.cpp \ - FileStream/FileStream.cpp + FileStream/FileStream.cpp \ + Md5/Md5.cpp HEADERS += \ Parser.h \ @@ -99,7 +100,8 @@ HEADERS += \ DataReader/ConfigHeaderReader.h \ Json/json.hpp \ DataReader/TemperatureDataReader.h \ - FileStream/FileStream.h + FileStream/FileStream.h \ + Md5/Md5.h INCLUDEPATH += $$PWD/../thirdParty/include diff --git a/src/Parser.pro.user b/src/Parser.pro.user index 9a0535a..0b7aff1 100644 --- a/src/Parser.pro.user +++ b/src/Parser.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/src/ParserPrivate.cpp b/src/ParserPrivate.cpp index 9899727..cbaaebb 100644 --- a/src/ParserPrivate.cpp +++ b/src/ParserPrivate.cpp @@ -15,6 +15,7 @@ #include "DataReader/TemperatureDataReader.h" #include "DataReader/ConfigHeaderReader.h" #include "FileStream/FileStream.h" +#include "Md5/Md5.h" #include #include @@ -88,6 +89,15 @@ namespace } return ParserMode::KITMode; } + + std::string charToHex(char c) + { + std::string hexString; + static const char hexChars[] = "0123456789ABCDEF"; + hexString += hexChars[(c >> 4) & 0xF]; + hexString += hexChars[c & 0xF]; + return hexString; + } } ParserPrivate::ParserPrivate(const std::string& aPath, AscanDataType aDataType) @@ -563,6 +573,44 @@ void ParserPrivate::getAscanDataOfCEMeasuredInThread(std::shared_ptr a } CEMeasuredData ParserPrivate::getAllCEMeasuredData(ShotList* aShotList) +{ + switch(mMode) + { + case ParserMode::HJMode : + return getAllCEMeasuredDataFromHJData(); + case ParserMode::KITMode : + return getAllCEMeasuredDataFromKITData(aShotList); + } +} + +CEMeasuredData ParserPrivate::getAllCEMeasuredDataFromHJData() +{ + std::string ceMeasuredFile = FileListHelper::getCEMeasuredFileFromHJData(mPath); + if(ceMeasuredFile.empty()) + { + return CEMeasuredData(); + } + FileStream stream; + CEMeasuredData result(mDataLength); + stream.open(ceMeasuredFile.c_str()); + for(unsigned long long i=0; ihasCEMeasured(); + } +} + +bool ParserPrivate::verifyHashValue() +{ + std::string hashValue = getHashValue(); + const std::string configFile = mPath + SLASH_CHAR + HJDTA_CONIFGBIN; + std::ifstream stream; + stream.open(configFile, std::ios_base::binary | std::ios::in); + stream.seekg(0, std::ios::end); + unsigned long long fileSize = (unsigned long long)stream.tellg() - 16; + stream.seekg(0, std::ios::beg); + char* buffer = new char[fileSize]; + unsigned char* result = new unsigned char[16]; + stream.read(buffer, fileSize); + MD5_CTX md5; + MD5Init(&md5); + MD5Update(&md5, (unsigned char*)buffer, fileSize); + MD5Final(&md5, result); + std::string md5Hex; + for (int i = 0; i < 16; i++) + { + md5Hex += charToHex(result[i]); + } + stream.close(); + delete [] buffer; + delete [] result; + return md5Hex == hashValue; +} + +std::string ParserPrivate::getHashValue() +{ + const std::string configFile = mPath + SLASH_CHAR + HJDTA_CONIFGBIN; + std::ifstream stream; + stream.open(configFile, std::ios_base::binary | std::ios::in); + stream.seekg(mConfigHeader.getMD5Position(),std::ios::beg); + unsigned long long length = mConfigHeader.getMD5Length(); + char* hashValue = new char[length]; + stream.read(hashValue, length); + + std::string md5Hex; + for (int i = 0; i < length; i++) + { + md5Hex += charToHex(hashValue[i]); + } + delete[] hashValue; + return md5Hex; +} + diff --git a/src/ParserPrivate.h b/src/ParserPrivate.h index 7ff1745..e4a5efe 100644 --- a/src/ParserPrivate.h +++ b/src/ParserPrivate.h @@ -48,7 +48,8 @@ public: PatientData getPatientData(); TemperatureData getTemperatureData(); std::shared_ptr getShotList(); - + bool hasCEMeasured(); + bool verifyHashValue(); private: void getAscanDataOfMotorPositionInThread(std::shared_ptr aShotList, OneTasAScanData aOneTasAscanData, unsigned short aSenderTasNum, unsigned short aFileNum, unsigned short aLoopNum); @@ -57,6 +58,9 @@ private: void readAscanData(FileStream* aStream, AScanData aAScanData); void readOneTasAscanData(FileStream* aStream, unsigned long long* aIndex, OneTasAScanData aOneTasAscan); double getAmplification(short aValue); + CEMeasuredData getAllCEMeasuredDataFromHJData(); + CEMeasuredData getAllCEMeasuredDataFromKITData(ShotList* aShotList); + std::string getHashValue(); void initParser(); void initShotList(); void initCEData();