[abcd 4 6 61] [dabc 11 10 62] [cdab 2 15 63] [bcda 9 21 64]
/* 然后进行如下操作 */
a = a + aa
b = b + bb
c = c + cc
d = d + dd
next i /* 结束对i的循环*/
第六步,输出结果。
a,b,c,d连续存放,共16个字节,128位。按十六进制依次输出这个16个字节。
最后,用程序语言实现算法后,可以输入以下几个信息对程序作一个简单的测试,
看看程序有没有错误。
md5 ("") = d41d8cd98f00b204e9800998ecf8427e
md5 ("a") = 0cc175b9c0f1b6a831c399e269772661
md5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
md5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
md5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
md5 ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
md5 ("123456789012345678901234567890123456789012345678901234567890123456789
01234567890") = 57edf4a22be3c955ac49da2e2107b67a
md5算法之c#程序
md5算法比较特别,最适合用汇编语言来写,好多高级语言对之无能无力或效率极低。
比如我最开始尝试用python和euphoria编写,发现不太容易。相比而言,c#作为c家簇
中新兴的一门.net语言,功能比较全面。花了一晚上的工夫终于用c#最先实现了md5。
主要是由于对算法的一些细节不太注意,结果输出总是不对,调试了好长时间。
[code]
//源文件:md5.cs
// md5 alogrithm
// by rufi 2004.6.20 http://rufi.yculblog.com/
using system;
using system.collections;
using system.io;
public class md5 {
//static state variables
private static uint32 a;
private static uint32 b;
private static uint32 c;
private static uint32 d;
//number of bits to rotate in tranforming
private const int s11 = 7;
private const int s12 = 12;
private const int s13 = 17;
private const int s14 = 22;
private const int s21 = 5;
private const int s22 = 9;
private const int s23 = 14;
private const int s24 = 20;
private const int s31 = 4;
private const int s32 = 11;
private const int s33 = 16;
private const int s34 = 23;
private const int s41 = 6;
private const int s42 = 10;
private const int s43 = 15;
private const int s44 = 21;
/* f, g, h and i are basic md5 functions.
* 四个非线性函数:
*
* f(x,y,z) =(x&y)|((~x)&z)
* g(x,y,z) =(x&z)|(y&(~z))
* h(x,y,z) =x^y^z
* i(x,y,z)=y^(x|(~z))
*
* (&与,|或,~非,^异或)
*/
private static uint32 f(uint32 x,uint32 y,uint32 z){
return (x&y)|((~x)&z);
}
private static uint32 g(uint32 x,uint32 y,uint32 z){
return (x&z)|(y&(~z));
}
private static uint32 h(uint32 x,uint32 y,uint32 z){
return x^y^z;
}
private static uint32 i(uint32 x,uint32 y,uint32 z){
return y^(x|(~z));
}
/* ff, gg, hh, and ii transformations for rounds 1, 2, 3, and 4.
* rotation is separate from addition to prevent recomputation.
*/
private static void ff(ref uint32 a,uint32 b,uint32 c,uint32 d,uint32 mj,int s,uint32 ti){
a = a + f(b,c,d) + mj + ti;
a = a << s | a >> (32-s);
a += b;
}
private static void gg(ref uint32 a,uint32 b,uint32 c,uint32 d,uint32 mj,int s,uint32 ti){
a = a + g(b,c,d) + mj + ti;
a = a << s | a >> (32-s);
a += b;
}
private static void hh(ref uint32 a,uint32 b,uint32 c,uint32 d,uint32 mj,int s,uint32 ti){
a = a + h(b,c,d) + mj + ti;
a = a << s | a >> (32-s);
a += b;
}
private static void ii(ref uint32 a,uint32 b,uint32 c,uint32 d,uint32 mj,int s,uint32 ti){
a = a + i(b,c,d) + mj + ti;
a = a << s | a >> (32-s);
a += b;
}
private static void md5_init(){
a=0x67452301; //in memory, this is 0x01234567
b=0xefcdab89; //in memory, this is 0x89abcdef
c=0x98badcfe; //in memory, this is 0xfedcba98
d=0x10325476; //in memory, this is 0x76543210
}
private static uint32[] md5_append(byte[] input){
int zeros=0;
int ones =1;
int size=0;
int n = input.length;
int m = n%64;
if( m < 56 ){
zeros = 55-m;