📄 sha_1.cpp
字号:
// SHA_1.cpp: implementation of the SHA_1 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SHA_1.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
struct Q
{
char c[4];
}A,B,C,D,E,K[4],Y[16],W[80],H0,H1,H2,H3,H4;
// 字符二进制转换
void BinaryConversion(char szchar, char *pBinary);
// 循环左移iMove位32位字,iMove表示左移的位数,*pWord是待移的字
void LeftMove32(int iMove, char *pWord);
// c1+c2的模 32bit 加法(最高位不进位)
void mod32add(char *pchar1, char *pchar2, char *pWord);
// 计算W[i]的函数
void GetW(int i);
// f函数
struct Q Function(int t,Q b,Q c,Q d);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SHA_1::SHA_1()
{
}
SHA_1::~SHA_1()
{
}
// 字符二进制转换
void BinaryConversion(char szchar, char *pBinary)
{
for (int i = 0; i < 8; i++)
{
if (( szchar & char(1)<<(8 - i) ) != 0)
{
pBinary[i] = '1';
}
else
{
pBinary[i] = '0';
}
}
pBinary[8] = '\0';
}
// 循环左移iMove位32位字,iMove表示左移的位数,*pWord是待移的字
void LeftMove32(int iMove, char *pWord)
{
int i = 0;
int *p = new int[33];
for(i = 0; i < 32; i++)
{
p[i] = (i + iMove) % 32 + 1;
}
p[32] = '\0';
char *temp = new char[5];
for (i = 0;i < 4; i++)
{
temp[i]=char(0);
}
temp[4] = '\0';
for (i = 0; i < 32; i++)
{
int t1 = (p[i] - 1) / 8;
int t2 = (p[i] - 1) % 8 + 1;
int j = i % 8 + 1;
if ((pWord[t1] & char(1) << (8 - t2)) != 0)
{
temp[i / 8] = (temp[i / 8]) | (char(1)<<(8 - j));
}
}
for (i = 0; i < 4; i++)
{
pWord[i] = temp[i];
}
delete temp;
delete p;
}
// c1+c2的模 32bit 加法(最高位不进位)
void mod32add(char *pchar1, char *pchar2, char *pWord)
{
//进位处理
int bj = 0;
for (int i = 0;i < 4; i++)
{
pWord[i] = char(0);
}
i=0;
while (i < 32)
{
int j = 8 - i % 8;
int d1 = (pchar1[i / 8] & char(1) << (8 - j));
int d2 = (pchar2[i / 8] & char(1) << (8 - j));
int s = d1 + d2 + bj;
if (s == 0)
{
bj = 0;
}
else if (s == 1)
{
bj = 0;
pWord[i/8] = (pWord[i / 8]) | (char(1) << ( 8 - j));
}
else if (s==2)
{
bj = 1;
}
else if (s==3)
{
bj = 1;
pWord[i / 8] = (pWord[i / 8]) | (char(1) << (8 - j));
}
i++;
}
}
// 计算W[i]的函数
void GetW(int i)
{
char c0,c1,c2,c3;
c0 = W[i - 16].c[0] ^ W[i - 14].c[0] ^ W[i - 8].c[0] ^ W[i - 3].c[0];
c1 = W[i - 16].c[1] ^ W[i - 14].c[1] ^ W[i - 8].c[1] ^ W[i - 3].c[1];
c2 = W[i - 16].c[2] ^ W[i - 14].c[2] ^ W[i - 8].c[2] ^ W[i - 3].c[2];
c3 = W[i - 16].c[3] ^ W[i - 14].c[3] ^ W[i - 8].c[3] ^ W[i - 3].c[3];
W[i].c[0] = c0;
W[i].c[1] = c1;
W[i].c[2] = c2;
W[i].c[3] = c3;
LeftMove32(1, W[i].c);
}
// f函数
struct Q Function(int t,Q b,Q c,Q d)
{
struct Q temp;
int i;
if (t >= 0 && t <= 19)
{
for (i = 0; i < 4; i++)
{
temp.c[i] = (b.c[i] & c.c[i]) | (~b.c[i] & d.c[i]);
}
}
else if (t >= 20 && t <= 39)
{
for (i = 0; i < 4; i++)
{
temp.c[i] = b.c[i] ^ c.c[i] ^ d.c[i];
}
}
else if (t >= 40 && t <= 59)
{
for (i = 0;i < 4; i++)
{
temp.c[i] = (b.c[i] & c.c[i]) | (b.c[i] & d.c[i]) | (c.c[i] & d.c[i]);
}
}
else
{
for (i = 0; i < 4; i++)
{
temp.c[i] = b.c[i] ^ c.c[i] ^ d.c[i];
}
}
return temp;
}
// SHA_1算法核心部分,计算消息摘要, strMessage为消息
CString SHA_1::SHA_1Arithmetic(CString strMessage)
{
//=========初始化缓冲区A,B,C,D,E========
A.c[0] = char(0x67); A.c[1] = char(0x45); A.c[2] = char(0x23); A.c[3] = char(0x01);
B.c[0] = char(0xEF); B.c[1] = char(0xCD); B.c[2] = char(0xAB); B.c[3] = char(0x89);
C.c[0] = char(0x98); C.c[1] = char(0xBA); C.c[2] = char(0xDC); C.c[3] = char(0xFE);
D.c[0] = char(0x10); D.c[1] = char(0x32); D.c[2] = char(0x54); D.c[3] = char(0x76);
E.c[0] = char(0xC3); E.c[1] = char(0xD2); E.c[2] = char(0xE1); E.c[3] = char(0xF0);
int i;
// 给H0,H1,H2,H3,H4负初值
for(i = 0;i < 4; i++)
{
H0.c[i] = A.c[i];
H1.c[i] = B.c[i];
H2.c[i] = C.c[i];
H3.c[i] = D.c[i];
H4.c[i] = E.c[i];
}
for (i = 0; i < 16; i++)
{
Y[i].c[0] = char(0);
Y[i].c[1] = char(0);
Y[i].c[2] = char(0);
Y[i].c[3] = char(0);
}
int len = strMessage.GetLength();
// 对消息进行补位补长操作
int addlength = 0;
addlength = 448 - (len * 8) % 512;
// addlength 的目的是直接将消息补成512的倍数
if (addlength <= 0)
{
addlength += 512;
}
int L = (len * 8 + addlength + 64) / 8 + 1;
char *MessageAddLong = new char[L];
for (i = 0; i < L; i++)
{
MessageAddLong[i]='\0';
}
for (i = 0; i < len; i++)
{
MessageAddLong[i] = strMessage.GetAt(i);
}
MessageAddLong[len] = char(-128);
for (i = len + 1; i < L - 1; i++)
{
MessageAddLong[i] = '\0';
}
MessageAddLong[L-1] = '\0';
// 求len的二进制
int temp = len;
int s = 1;
int r[64];
while(temp != 1)
{
r[s++] = temp % 2;
temp /= 2;
}
r[s] = 1;
r[s + 1] = -1;
// 附加长度值
for (i = 1;i <= s; i++)
{
if (r[i])
{
MessageAddLong[L - 2 - (i - 1) / 8] = MessageAddLong[L - 2 - (i - 1) / 8] | (char(1) << ((i - 1) % 8));
}
}
struct Q temp1, temp2, temp3, temp4;
int t = 0;
int length = 0;
//=======计算A,B,C,D,E==============
while(length < (L - 1))
{
for (i = 0;i < 16; i++)
{
for (int j = 0;j < 4; j++)
{
Y[i].c[j] = W[i].c[j] = MessageAddLong[length++];
}
}
for (i = 16;i < 80; i++)
{
GetW(i);
}
for (t=0;t<80;t++)
{
temp1 = A;
// 处理S5(A)
LeftMove32(5, temp1.c);
temp2 = B;
// 处理S30(B)
LeftMove32(30, temp2.c);
temp3 = Function(t,B,C,D);
for (i=0;i<4;i++)
{
temp4.c[i] = E.c[i] ^ temp3.c[i] ^ temp1.c[i] ^ W[t].c[i] ^K[t / 20].c[i];
}
A = temp4;
B = A;
C = temp2;
D = C;
E = D;
}
mod32add(A.c, A.c, H0.c);
mod32add(B.c, B.c, H1.c);
mod32add(C.c, C.c, H2.c);
mod32add(D.c, D.c, H3.c);
mod32add(E.c, E.c, H4.c);
}
// Message_Digest是未转化成二进制的消息摘要
char *Message_Digest = new char[21];
for (i = 0; i < 4; i++)
{
Message_Digest[i] = A.c[i];
Message_Digest[i+4] = B.c[i];
Message_Digest[i+8] = C.c[i];
Message_Digest[i+12] = D.c[i];
Message_Digest[i+16] = E.c[i];
}
Message_Digest[20]='\0';
// 以2进制的形式显示消息摘要
CString strMessageDigest = "";
for (i = 0;i < 20; i++)
{
char szBinary[9];
BinaryConversion(Message_Digest[i], szBinary);
strMessageDigest += szBinary;
}
delete Message_Digest;
delete MessageAddLong;
// 返回消息摘要
return strMessageDigest;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -