一方向ハッシュアルゴリズム(Hash)--MD 5アルゴリズム
5282 ワード
MD 5:また、メッセージ要約アルゴリズムとも呼ばれる.入力された任意の長さのメッセージに対して、固定長128ビットのメッセージダイジェストを生成する.MD 5のアルゴリズムはデータを可逆圧縮するため、つまり直接解析アルゴリズムによって、MD 5値を介して元の圧縮データを逆に取得することができなくなり、データチェックと暗号を回避するために使用されるプライバシーデータのコード保存が一般的である.
アルゴリズムステップ:
1.データ充填:その長さを512に対して取った残りは448に等しく、充填方法:まずメッセージの後に1つを追加し(bitで)、その後0で充填し、メモリ構造から見れば、メッセージの後に0 x 80を追加します.追加の長さは少なくとも1で、最大512.
2.長さを追加します.充填後の結果に64ビットのメッセージ長を添付します.メッセージ長が2^64を超える場合は64ビットのデータのみを使用します.第1のステップに第2のステップを加えると、ちょうど512の倍数になります.
3.初期化変数:標準パラメータ:A=0 X 67452301 h、B=0 XEFCS DAB 89 h、C=0 X 98BADCFEh、D=0 X 103325476 h、メモリに表示されているのは012345789 ABCDEFFDCBA 9876543210です.
4.データ処理:512ビットのパケットを単位としてメッセージを処理し、各パケットは16個の32ビットの配列に分解され、まず4つの補助関数を定義する.
F、G、H、Iに対応する演算関数は以下の通りです.
構成が一致しています.a、b、c、d:入力パラメータ(A、B、C、D)k:メッセージパケットが分割された16個の32ビット配列値s:循環左シフトビット数i:加算定数のid
アルゴリズムステップ:
1.データ充填:その長さを512に対して取った残りは448に等しく、充填方法:まずメッセージの後に1つを追加し(bitで)、その後0で充填し、メモリ構造から見れば、メッセージの後に0 x 80を追加します.追加の長さは少なくとも1で、最大512.
2.長さを追加します.充填後の結果に64ビットのメッセージ長を添付します.メッセージ長が2^64を超える場合は64ビットのデータのみを使用します.第1のステップに第2のステップを加えると、ちょうど512の倍数になります.
3.初期化変数:標準パラメータ:A=0 X 67452301 h、B=0 XEFCS DAB 89 h、C=0 X 98BADCFEh、D=0 X 103325476 h、メモリに表示されているのは012345789 ABCDEFFDCBA 9876543210です.
4.データ処理:512ビットのパケットを単位としてメッセージを処理し、各パケットは16個の32ビットの配列に分解され、まず4つの補助関数を定義する.
int F(int x, int y, int z)
{
return (x & y) | ((~x) & z);
}
int G(int x, int y, int z)
{
return (x & z) | ((~z) & y);
}
int H(int x, int y, int z)
{
return x ^ y ^ z;
}
int I(int x, int y, int z)
{
return y ^ (x | (~z));
}
その後、16個のデータとABCDの複製値をF、G、H、Iの四輪変換に参加し、演算完了後、変換前の初期値を一度に加算して、次のメッセージパケットの計算初期値として、すべてのメッセージパケットが演算されるまで、計算が完了する.F、G、H、Iに対応する演算関数は以下の通りです.
構成が一致しています.a、b、c、d:入力パラメータ(A、B、C、D)k:メッセージパケットが分割された16個の32ビット配列値s:循環左シフトビット数i:加算定数のid
void FF(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + F(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
void GG(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + G(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
void HH(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + H(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
void II(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + I(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
完全アルゴリズムは以下の通りです.#include
#define ROL(data,n) ((data >> (32 - n)) | (data << n))
#define BIG_ENDIAN_SWITCH_LITTLE_ENDIAN(X) X << 24 | X >> 24 | ((X << 8) & 0xFF0000) | ((X >> 8) & 0xFF00)
int F(int x, int y, int z)
{
return (x & y) | ((~x) & z);
}
int G(int x, int y, int z)
{
return (x & z) | ((~z) & y);
}
int H(int x, int y, int z)
{
return x ^ y ^ z;
}
int I(int x, int y, int z)
{
return y ^ (x | (~z));
}
void FF(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + F(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
void GG(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + G(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
void HH(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + H(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
void II(unsigned int* a, unsigned int b, unsigned int c, unsigned int d, unsigned int k, unsigned int s, unsigned int i)
{
*a = b + ROL((*a + I(b, c, d) + k + (unsigned int)(4294967296 * abs(sin(i)))), s);
}
int main()
{
//
unsigned char cValue[64] = {0};
unsigned int iValue[16] = { 0 };
char code[] = "zfy1996";
unsigned int len = strlen(code);
unsigned int len1 = strlen(code)*8;
memcpy(cValue, code, strlen(code));
cValue[strlen(code)] = 0x80;
memcpy(iValue, cValue, 64);
iValue[14] = strlen(code) * 8;
//
unsigned int A = 0x67452301, B = 0xefcdab89, C = 0x98badcfe, D = 0x10325476;
unsigned int a = A, b = B, c = C, d = D;
unsigned int s[64] = {
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
unsigned int k[64] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
typedef void(*func)(unsigned int*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int);
func fun[] = { FF,GG,HH,II };
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 16; j += 4)
{
fun[i](&a, b, c, d, iValue[k[16 * i + j]], s[16 * i + j], 16 * i + j + 1);
fun[i](&d, a, b, c, iValue[k[16 * i + j+1]], s[16 * i + j+1], 16 * i + j+2);
fun[i](&c, d, a, b, iValue[k[16 * i + j+2]], s[16 * i + j+2], 16 * i + j+3);
fun[i](&b, c, d, a, iValue[k[16 * i + j+3]], s[16 * i + j+3], 16 * i + j+4);
}
}
A += a;
B += b;
C += c;
D += d;
//
printf("%X%X%X%X
",
BIG_ENDIAN_SWITCH_LITTLE_ENDIAN(A),
BIG_ENDIAN_SWITCH_LITTLE_ENDIAN(B),
BIG_ENDIAN_SWITCH_LITTLE_ENDIAN(C),
BIG_ENDIAN_SWITCH_LITTLE_ENDIAN(D));
}