- 締切済み
どういった計算をしてるのか知りたい
以下のコードはある特殊なファイルのCRCを算出するものですが、算出できてもこのコードのプログラムだと算出だけでCRCをうまく合わせられるように変更ができないので、計算してバイナリ上で変更できるように計算公式が知りたいです。 ☆CRC.cpp Hidden Block (10 post(s) are required, you have 32): #ifndef _CCRC32_CPP #define _CCRC32_CPP #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include "CRC.H" void CCRC32::Initialize(void) { memset(&this->ulTable, 0, sizeof(this->ulTable)); // 256 values representing ASCII character codes. for(int iCodes = 0; iCodes <= 0xFF; iCodes++) { this->ulTable[iCodes] = this->Reflect(iCodes, 8) << 24; for(int iPos = 0; iPos < 8; iPos++) { this->ulTable[iCodes] = (this->ulTable[iCodes] << 1) ^ (this->ulTable[iCodes] & (1 << 31) ? CRC32_POLYNOMIAL : 0); } this->ulTable[iCodes] = this->Reflect(this->ulTable[iCodes], 32); } } // Reflection is a requirement for the official CRC-32 standard. // You can create CRCs without it, but they won't conform to the standard. unsigned long CCRC32::Reflect(unsigned long ulReflect, char cChar) { unsigned long ulValue = 0; // Swap bit 0 for bit 7 bit 1 For bit 6, etc.... for(int iPos = 1; iPos < (cChar + 1); iPos++) { if(ulReflect & 1) ulValue |= 1 << (cChar - iPos); ulReflect >>= 1; } return ulValue; } unsigned long CCRC32::FileCRC(const char *sFileName) { unsigned long ulCRC = 0xffffffff; FILE *fSource = NULL; unsigned char sBuf[CRC32BUFSZ]; int iBytesRead = 0; if( (fSource = fopen(sFileName, "rb")) == NULL) { return 0xffffffff; } do{ iBytesRead = fread(sBuf, sizeof(char), CRC32BUFSZ, fSource); this->PartialCRC(&ulCRC, sBuf, iBytesRead); }while(iBytesRead == CRC32BUFSZ); fclose(fSource); return(ulCRC ^ 0xffffffff); } unsigned long CCRC32::FullCRC(unsigned char *sData, unsigned long ulLength) { unsigned long ulCRC = 0xffffffff; this->PartialCRC(&ulCRC, sData, ulLength); return ulCRC ^ 0xffffffff; } //For Example usage example, see FileCRC(). void CCRC32::PartialCRC(unsigned long *ulInCRC, unsigned char *sData, unsigned long ulLength) { while(ulLength--) { *ulInCRC = (*ulInCRC >> 8) ^ this->ulTable[(*ulInCRC & 0xFF) ^ *sData++]; } } #endif ☆CRC.h Hidden Block (10 post(s) are required, you have 32): #ifndef _CCRC32_H #define _CCRC32_H // This is the official polynomial used by CRC-32 in PKZip, WinZip and Ethernet. #define CRC32_POLYNOMIAL 0x04c11db7 #define CRC32BUFSZ 1024 //Used for FileCRC() class CCRC32{ public: void Initialize(void); unsigned long FileCRC(const char *sFileName); unsigned long FullCRC(unsigned char *sData, unsigned long ulLength); void PartialCRC(unsigned long *ulInCRC, unsigned char *sData, unsigned long ulLength); private: unsigned long Reflect(unsigned long ulReflect, char cChar); unsigned long ulTable[256]; // CRC lookup table array. }; #endif わかる方よければ教えてください。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス >MD5等と同じということなんでしょうか? ↑ CRC値からデータ内容に戻せないという部分は同じです。 でもCRC32程度では改竄とか、データ内容が違ってもCRC値が 同じになる衝突が起こりやすいです。 >その8桁がどのようにして算出されているのかが知りたいのですが ↑ 簡単に説明すると生成多項式という『決まった数』でデータを 巨大なビット列と見なして割り算します。 そして余りをどんどん求めます。 最終的に残った余りがCRC値になります。 >表示しているプログラムのソースコードだけでは不足ということでしょうか? ↑ 誰が作ったソースでしょうか。 あまり人の作ったソースを解読する気はないです。 次のリンクが参考になりませんか。 http://kone.vis.ne.jp/diary/diaryb07.html 他にも『アルゴリズム辞典』に載っています。 http://www.amazon.co.jp/dp/4320027094/ http://oku.edu.mie-u.ac.jp/~okumura/algo/ 『生成多項式』は次のリンクを参考にして下さい。 http://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E5%86%97%E9%95%B7%E6%A4%9C%E6%9F%BB >ちなみに暗号化キーはFCCFABのようです。 ↑ 暗号キーにCRC32を利用しているのですか? あまり安全ではありませんね。 MD5のハッシュ値を使った方が改竄されず、 ハッシュ値の衝突も起こりにくいので安全になります。 ・その他 SHA1、SHA256、SHA384、SHA512などもあります。 (こちらの方がもっと安全)
- gau_puzzler
- ベストアンサー率48% (39/81)
crcは一方向の計算ロジックなので、元に戻せません crc32ですから、単純に考えれば42億通りの組み合わせを行えば一致します (というか、合わせるのは無理と考えたほうが無難) ※復元できるものにはlzh圧縮、zip圧縮などがあります パスワードの暗号などは復元できない圧縮となります
補足
MD5等と同じということなんでしょうか? とりあえずこのソースをコンパイルした実行ファイルを起動して、 あるファイルをドラッグすると8桁の文字列が表示されます。 その8桁がどのようにして算出されているのかが知りたいのですが、表示しているプログラムのソースコードだけでは不足ということでしょうか? ちなみに暗号化キーはFCCFABのようです。
- Tacosan
- ベストアンサー率23% (3656/15482)
中身を見る気は全くありませんが, CRC がどのように数学的に定義されているかご存知ですか?
補足
すいません。あまりよくわかってないのでここで質問させていただいてます。
お礼
やはり他人のソースを解読を言うのは好まれないケースが多そうですね 参考リンクをたくさんありがとうございました。 いろいろ調べてみることにします。