Created
November 11, 2012 03:58
-
-
Save hirosof/4053601 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "CHSSHA1.h" | |
| #include <cstdio> | |
| using namespace std; | |
| //メッセージダイジェスト初期値 | |
| const unsigned __int32 CHSSHA1::DefaultMessageDijest[5] = { | |
| 0x67452301 , | |
| 0xefcdab89 , | |
| 0x98badcfe , | |
| 0x10325476 , | |
| 0xc3d2e1f0 | |
| }; | |
| CHSSHA1::CHSSHA1(){ | |
| this->Initialization(); | |
| } | |
| void CHSSHA1::New(void){ | |
| this->Initialization(); | |
| } | |
| void CHSSHA1::Initialization(void){ | |
| memcpy(this->MessageDijest , this->DefaultMessageDijest , sizeof(this->DefaultMessageDijest)); | |
| this->DataSize = 0; | |
| memset(this->TempData , NULL , sizeof(this->TempData)); | |
| this->TmpDataIdx = 0; | |
| this->QuitPublish = false; | |
| } | |
| int CHSSHA1::StrlenByte(char *lpStringA){ | |
| int size = 0; | |
| if(!lpStringA)return 0; | |
| while(*lpStringA){ | |
| size++; | |
| lpStringA++; | |
| } | |
| return size * sizeof(char); | |
| } | |
| int CHSSHA1::StrlenByte(unsigned char *lpStringA){ | |
| int size = 0; | |
| if(!lpStringA)return 0; | |
| while(*lpStringA){ | |
| size++; | |
| lpStringA++; | |
| } | |
| return size * sizeof(unsigned char); | |
| } | |
| int CHSSHA1::StrlenByte(wchar_t *lpStringW){ | |
| int size = 0; | |
| if(!lpStringW)return 0; | |
| while(*lpStringW){ | |
| size++; | |
| lpStringW++; | |
| } | |
| return size * sizeof(wchar_t); | |
| } | |
| unsigned __int32 CHSSHA1::Rotate(unsigned __int32 x,int bit){ | |
| unsigned __int32 rot = bit%32; | |
| return (x >> (32 - rot)) | (x << rot); | |
| } | |
| unsigned __int32 CHSSHA1::GetConstData(int constant){ | |
| if(constant<=19)return 0x5a827999; | |
| else if(constant<=39)return 0x6ed9eba1; | |
| else if(constant<=59)return 0x8f1bbcdc; | |
| else if(constant<=79)return 0xca62c1d6; | |
| return 0; | |
| } | |
| unsigned __int32 CHSSHA1::LogicalExp(int constant, unsigned __int32 x ,unsigned __int32 y ,unsigned __int32 z){ | |
| if(constant<=19)return (x&y)|(~x&z); | |
| else if(constant<=39)return x^y^z; | |
| else if(constant<=59)return (x&y)|(x&z)|(y&z); | |
| else if(constant<=79)return x^y^z; | |
| return 0; | |
| } | |
| void CHSSHA1::HashBlock(){ | |
| unsigned __int32 md[5]; //メッセージダイジェストに加算する値 | |
| unsigned __int32 Data[80]; //ハッシュブロックデータ | |
| //入力データを16ブロックに分割 | |
| for(int i = 0 , j = 0 ; i < 16 ; i++ , j+=4){ | |
| Data[i] = this->TempData[j] << 24; | |
| Data[i] |= this->TempData[j + 1] << 16; | |
| Data[i] |= this->TempData[j + 2] << 8; | |
| Data[i] |= this->TempData[j + 3]; | |
| } | |
| //Data[16]~Data[79]までローテート関数を使ってデータ準備 | |
| for(int i=16 ; i <= 79 ; i++){ | |
| unsigned __int32 rotbase; | |
| rotbase = Data[i-3] ^ Data[i-8] ^ Data[i-14] ^ Data[i-16]; | |
| Data[i] = this->Rotate(rotbase , 1); | |
| } | |
| //メッセージダイジェストをコピー | |
| memcpy(md , this->MessageDijest , sizeof(md)); | |
| //Data[0] ~ Data[79]まで使用してメッセージダイジェストに加算する値を算出 | |
| for(int i=0 ; i <= 79 ; i++){ | |
| unsigned __int32 temp; | |
| temp = this->Rotate(md[0] , 5) + this->LogicalExp(i , md[1] , md[2] , md[3]) + md[4]; | |
| temp+=Data[i] + this->GetConstData(i); | |
| md[4] = md[3]; | |
| md[3] = md[2]; | |
| md[2] = this->Rotate(md[1],30); | |
| md[1] = md[0]; | |
| md[0] = temp; | |
| } | |
| //メッセージダイジェストに加算 | |
| for(int i = 0 ; i < 5 ; i++) | |
| this->MessageDijest[i] += md[i]; | |
| //64byte DataSize加算 | |
| this->DataSize += 64; | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Insert(char *lpStringA){ | |
| return this->Insert(lpStringA , this->StrlenByte(lpStringA)); | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Insert(unsigned char *lpStringA){ | |
| return this->Insert(lpStringA , this->StrlenByte(lpStringA)); | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Insert(wchar_t *lpStringW) { | |
| return this->Insert(lpStringW , this->StrlenByte(lpStringW)); | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Insert(void *lpData , __int64 size){ | |
| __int8 *lpByteData; | |
| __int64 idx[2]= { this->TmpDataIdx , 0}; | |
| if(!lpData || (size <= 0))return CHSSHA1_ERROR_FALSE; | |
| else if( this->QuitPublish ) return CHSSHA1_ERROR_QUITPABLISHED; | |
| lpByteData = (__int8*)lpData; | |
| if(idx[0] + size >= 64){ | |
| __int64 tmp = 64 - idx[0]; | |
| __int64 NumBlock , NumRest; | |
| memcpy(this->TempData + idx[0] , lpByteData , (__int32)tmp); | |
| this->HashBlock(); | |
| idx[0] = 0; idx[1] += tmp; | |
| lpByteData += tmp; | |
| NumBlock = (size - idx[1]) / 64; | |
| NumRest = (size - idx[1]) % 64; | |
| for(int i = 0 ; i < NumBlock ; i++){ | |
| memcpy(this->TempData , lpByteData + 64*i , 64); | |
| this->HashBlock(); | |
| } | |
| memcpy(this->TempData , lpByteData + 64*NumBlock , (__int32)NumRest); | |
| }else{ | |
| memcpy(this->TempData + idx[0] , lpByteData , (__int32)size); | |
| } | |
| this->TmpDataIdx = (this->TmpDataIdx + size) % 64; | |
| return CHSSHA1_ERROR_TRUE; | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Publish(char *lpStringA){ | |
| return this->Publish(lpStringA , this->StrlenByte(lpStringA)); | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Publish(unsigned char *lpStringA){ | |
| return this->Publish(lpStringA , this->StrlenByte(lpStringA)); | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Publish(wchar_t *lpStringW) { | |
| return this->Publish(lpStringW , this->StrlenByte(lpStringW)); | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Publish(void *InputData , __int64 Size){ | |
| __int64 bitsize , revbitsize = 0; | |
| __int8 *lpbitsize,*lprevbitsize; | |
| if(this->QuitPublish)return CHSSHA1_ERROR_QUITPABLISHED; | |
| //最終追加 | |
| this->Insert(InputData,Size); | |
| bitsize = (this->DataSize + this->TmpDataIdx) * 8; | |
| this->TempData[this->TmpDataIdx] = (unsigned __int8)0x80; | |
| memset(this->TempData + this->TmpDataIdx + 1 , 0 , 64 - (this->TmpDataIdx + 1 )); | |
| if(this->TmpDataIdx >= 56){ | |
| this->HashBlock(); | |
| memset(this->TempData , 0 , 56); | |
| } | |
| lpbitsize = (__int8*)&bitsize; | |
| lprevbitsize = (__int8*)&revbitsize; | |
| for(int i = 0 ; i < 8 ; i++)*(lprevbitsize + 7 - i) = *(lpbitsize + i); | |
| memcpy(this->TempData + 56 , lprevbitsize , 8); | |
| this->HashBlock(); | |
| this->QuitPublish = true; | |
| return CHSSHA1_ERROR_TRUE; | |
| } | |
| int CHSSHA1::Get(char *lpTextA , int size , CHSSHA1_TOSTRFLAG flag, char split_char){ | |
| char text[45]; | |
| if(!this->QuitPublish)return 0; | |
| switch (flag){ | |
| case CHSSHA1_TOSTRFLAG_SMALL: | |
| sprintf_s(text , "%x%x%x%x%x" , this->MessageDijest[0] , | |
| this->MessageDijest[1], | |
| this->MessageDijest[2], | |
| this->MessageDijest[3], | |
| this->MessageDijest[4]); | |
| break; | |
| case CHSSHA1_TOSTRFLAG_SMALL_DELIMITER: | |
| sprintf_s(text , "%x%c%x%c%x%c%x%c%x" , this->MessageDijest[0] ,split_char, | |
| this->MessageDijest[1],split_char, | |
| this->MessageDijest[2],split_char, | |
| this->MessageDijest[3],split_char, | |
| this->MessageDijest[4]); | |
| break; | |
| case CHSSHA1_TOSTRFLAG_BIG: | |
| sprintf_s(text , "%X%X%X%X%X" , this->MessageDijest[0] , | |
| this->MessageDijest[1], | |
| this->MessageDijest[2], | |
| this->MessageDijest[3], | |
| this->MessageDijest[4]); | |
| break; | |
| case CHSSHA1_TOSTRFLAG_BIG_DELIMITER: | |
| sprintf_s(text , "%X%c%X%c%X%c%X%c%X" , this->MessageDijest[0] ,split_char, | |
| this->MessageDijest[1],split_char, | |
| this->MessageDijest[2],split_char, | |
| this->MessageDijest[3],split_char, | |
| this->MessageDijest[4]); | |
| break; | |
| } | |
| int isize = this->StrlenByte(text); | |
| if(lpTextA && (isize + 1 <= size)) sprintf_s(lpTextA , size , "%s" , text); | |
| return isize; | |
| } | |
| int CHSSHA1::Get(wchar_t *lpTextW , int size , CHSSHA1_TOSTRFLAG flag, wchar_t split_char){ | |
| wchar_t text[45]; | |
| if(!this->QuitPublish)return 0; | |
| switch (flag){ | |
| case CHSSHA1_TOSTRFLAG_SMALL: | |
| swprintf_s(text , L"%x%x%x%x%x" , this->MessageDijest[0] , | |
| this->MessageDijest[1], | |
| this->MessageDijest[2], | |
| this->MessageDijest[3], | |
| this->MessageDijest[4]); | |
| break; | |
| case CHSSHA1_TOSTRFLAG_SMALL_DELIMITER: | |
| swprintf_s(text , L"%x%c%x%c%x%c%x%c%x" , this->MessageDijest[0] ,split_char, | |
| this->MessageDijest[1],split_char, | |
| this->MessageDijest[2],split_char, | |
| this->MessageDijest[3],split_char, | |
| this->MessageDijest[4]); | |
| break; | |
| case CHSSHA1_TOSTRFLAG_BIG: | |
| swprintf_s(text , L"%X%X%X%X%X" , this->MessageDijest[0] , | |
| this->MessageDijest[1], | |
| this->MessageDijest[2], | |
| this->MessageDijest[3], | |
| this->MessageDijest[4]); | |
| break; | |
| case CHSSHA1_TOSTRFLAG_BIG_DELIMITER: | |
| swprintf_s(text , L"%X%c%X%c%X%c%X%c%X" , this->MessageDijest[0] ,split_char, | |
| this->MessageDijest[1],split_char, | |
| this->MessageDijest[2],split_char, | |
| this->MessageDijest[3],split_char, | |
| this->MessageDijest[4]); | |
| break; | |
| } | |
| int isize = this->StrlenByte(text)/sizeof(wchar_t); | |
| if(lpTextW && (isize + 1 <= size)) swprintf_s(lpTextW , size , L"%s" , text); | |
| return isize; | |
| } | |
| CHSSHA1_ERROR CHSSHA1::Get(unsigned __int32 *lpData){ | |
| if(!this->QuitPublish)return CHSSHA1_ERROR_ISNOTQUITPABLISH; | |
| if(lpData){ | |
| memcpy(lpData , this->MessageDijest , sizeof(this->MessageDijest)); | |
| return CHSSHA1_ERROR_TRUE; | |
| } | |
| return CHSSHA1_ERROR_FALSE; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <memory.h> | |
| #ifndef NULL | |
| #define NULL 0 | |
| #endif | |
| enum CHSSHA1_ERROR | |
| { | |
| CHSSHA1_ERROR_FALSE = 0, | |
| CHSSHA1_ERROR_TRUE, | |
| CHSSHA1_ERROR_ISNOTQUITPABLISH, | |
| CHSSHA1_ERROR_QUITPABLISHED | |
| }; | |
| enum CHSSHA1_TOSTRFLAG | |
| { | |
| CHSSHA1_TOSTRFLAG_SMALL = 0, | |
| CHSSHA1_TOSTRFLAG_SMALL_DELIMITER, | |
| CHSSHA1_TOSTRFLAG_BIG, | |
| CHSSHA1_TOSTRFLAG_BIG_DELIMITER, | |
| }; | |
| #ifndef __CHSSHA1_H__ | |
| #define __CHSSHA1_H__ | |
| class CHSSHA1 | |
| { | |
| //private 変数 | |
| private: | |
| static const unsigned __int32 DefaultMessageDijest[5]; | |
| unsigned __int32 MessageDijest[5]; | |
| __int64 DataSize; | |
| unsigned __int8 TempData[64]; | |
| int TmpDataIdx; | |
| bool QuitPublish; | |
| //private 関数 | |
| private: | |
| unsigned __int32 Rotate(unsigned __int32,int); | |
| unsigned __int32 GetConstData(int); | |
| unsigned __int32 LogicalExp(int , unsigned __int32,unsigned __int32,unsigned __int32); | |
| void HashBlock(void); | |
| int StrlenByte(char*); | |
| int StrlenByte(unsigned char*); | |
| int StrlenByte(wchar_t*); | |
| //public 関数 | |
| public: | |
| CHSSHA1(); | |
| void New(void); | |
| void Initialization(void); | |
| CHSSHA1_ERROR Insert(void* , __int64); | |
| CHSSHA1_ERROR Insert(char*); | |
| CHSSHA1_ERROR Insert(wchar_t*); | |
| CHSSHA1_ERROR Insert(unsigned char*); | |
| CHSSHA1_ERROR Publish(void *InputData = NULL , __int64 Size = NULL); | |
| CHSSHA1_ERROR Publish(char*); | |
| CHSSHA1_ERROR Publish(wchar_t*); | |
| CHSSHA1_ERROR Publish(unsigned char*); | |
| int Get(char *lpTextA , int size , CHSSHA1_TOSTRFLAG flag = CHSSHA1_TOSTRFLAG_BIG_DELIMITER, char split_char = ' '); | |
| int Get(wchar_t *lpTextW , int size , CHSSHA1_TOSTRFLAG flag = CHSSHA1_TOSTRFLAG_BIG_DELIMITER, wchar_t split_char = ' '); | |
| CHSSHA1_ERROR Get(unsigned __int32 *); | |
| }; | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <iomanip> | |
| #include "CHSSHA1.h" | |
| using namespace std; | |
| int main(void){ | |
| CHSSHA1 sha1; | |
| char StringA[512]; | |
| char hash[45]; | |
| cout << "SHA1 - ハッシュ を計算したい文字列を512文字以内で入力してください" << endl ; | |
| cout << "入力文字列:" ; | |
| cin >> StringA ; | |
| sha1.Publish(StringA); | |
| sha1.Get(hash , 45 , CHSSHA1_TOSTRFLAG_SMALL); | |
| cout << "SHA1値:" << hash << endl ; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment