Skip to content

Instantly share code, notes, and snippets.

@hirosof
Created November 11, 2012 03:58
Show Gist options
  • Select an option

  • Save hirosof/4053601 to your computer and use it in GitHub Desktop.

Select an option

Save hirosof/4053601 to your computer and use it in GitHub Desktop.
#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;
}
#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
#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