一方向ハッシュアルゴリズム(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つの補助関数を定義する.
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)); }