Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 计算不带库的空字符串的MD5摘要_C_Md5 - Fatal编程技术网

C 计算不带库的空字符串的MD5摘要

C 计算不带库的空字符串的MD5摘要,c,md5,C,Md5,我正在努力学习MD5算法,并“从头开始”编写一个c程序。我想计算空字符串的MD5摘要(并从那里开始) 文档(对应的RFC)看起来很混乱,但我认为我已经遵循了它。我复制了函数和常量的定义(在main()之前的所有内容)并进行了取整。我的输入只是所需的填充(因为输入是空字符串),它是一个1位,后跟5110位(消息的表示应该是所有0) 状态[4]是缓冲区数组 我将输入复制到一个无符号长int数组中,以便将其作为函数的整数处理,然后将其复制回字符数组 #include <stdio.h> #

我正在努力学习MD5算法,并“从头开始”编写一个c程序。我想计算空字符串的MD5摘要(并从那里开始)

文档(对应的RFC)看起来很混乱,但我认为我已经遵循了它。我复制了函数和常量的定义(在main()之前的所有内容)并进行了取整。我的输入只是所需的填充(因为输入是空字符串),它是一个
1
位,后跟511
0
位(消息的表示应该是所有
0

状态[4]
是缓冲区数组

我将输入复制到一个
无符号长int
数组中,以便将其作为函数的整数处理,然后将其复制回字符数组

#include <stdio.h>
#include <math.h>
#include <string.h>

typedef unsigned char *POINTER;
typedef unsigned short int UINT2;
typedef unsigned long int UINT4;

#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21

#define F(x,y,z) ((x & y) | (~x & z))
#define G(x,y,z) ((x & z) | (~z & y))
#define H(x,y,z) (x ^ y ^ z)
#define I(x,y,z) (y ^ (x | ~z))

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

#define FF(a, b, c, d, x, s, ac) { \
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }
#define GG(a, b, c, d, x, s, ac) { \
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }
#define HH(a, b, c, d, x, s, ac) { \
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }
#define II(a, b, c, d, x, s, ac) { \
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
  }

int main () {

int i;
char input[64]={0};
char output[64]={0};
unsigned long int x[16]={0};
unsigned long int state[4]={0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};

//Initialize variables:
int a = state[0];   //A
int b = state[1];   //B
int c = state[2];   //C
int d = state[3];   //D

input[0]=0x80;

memcpy(x, input, 64);

/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;

memcpy(output, state, 64);

for (i=0;i<=31;i++) {
    printf("%02x ", output[2*i]);
}

return 0;
}
当它应该(可以想象)是空字符串的MD5摘要时

d4 1d 8c d9 8f 00 b2 04 e9 80 09 98 ec f8 42 7e

IIRC,
char
可以是有符号的,也可以是无符号的,这取决于您的编译器/体系结构等。在您的例子中,它似乎是有符号的。因此,如果设置了顶部位,当您打印它时,printf认为它是一个负数,并吐出所有前导的1位。它变得更加混乱,因为您的字符可能有8位长,但printf显示的是32位。最简单的带回家的消息是使用
unsigned char
来处理这类事情,或者更好地使用
#包括“inttypes.h”
,并使用像
uint8\t
这样的显式消息。。。。换句话说,
输入
输出
数组应该是
无符号字符
的数组。但是还有另一个问题。通过我之前评论中建议的修改,我得到了这个输出
85 94 58 f9 3f ed 87 c1 cc cc 80 00 00 00 00 00 00 00 00 00 00 00
cc
s建议一些未初始化的变量或超出范围的数组索引这:
memcpy(x,input,64)
(以及其他类似的人)很可能是你问题的一大部分。memcpy处理的是字节,而不是“类型”。因此,您不是将64个字符复制到64个整数,而是将字符数组的前64个字节(在本例中,这实际上是您想要的)复制到整数数组的前64个字节(这不是您想要的,因为每个整数可能有4个字节长)。试着用循环复制,一次复制一个项目;您正在复制正确数量的数据,但您不一定依赖于它以正确的顺序被复制,这取决于您的机器的端度。很抱歉给你带来了困惑。
d4 1d 8c d9 8f 00 b2 04 e9 80 09 98 ec f8 42 7e