我已经连续几个小时试图解决这个问题我不完全确定是什么导致了错误的输出显然很难找到因为它是一种哈希算法我知道我的分块代码不完整它仍在进行中并且我一直在编程一周
/*
* MD5 Implementation in C
* Created by Caelan Ireland 2023
*/
//#include "MD5.h"
#include <stdint.h> // uint32_t
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <endian.h>
#include <stdint.h> // needed?
// make sure to use -lm tag when compiling with gcc
#include <math.h>
// To Do: Essential Items for Understanding MD5
// 5. Divide up
// 6. Finish ABCD funct
// 4. Padding (Incomplete) incl error checks
// 4 32 bit words called A, B, C and D
#define A 0x67452301
#define B 0xEFCDAB89
#define C 0x98BADCFE
#define D 0x10325476
// remember Let [abcd k s i] ------------------------------------------->>>>>>>
const uint32_t 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
};
//const uint32_t MD[4] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476};
// unsigned int T[64];
// for(int i = 0; i < 64; i++) {
// T[i] = floor(pow(2, 32) * fabs(sin(i + 1))); // fabs fixed wrap or abs? floorf for floats
// printf("0x%08x\n", T[i]); // %u
// };
// precomputed hashes
const uint32_t K[64] = { // T
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
};
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#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, k, s, i) \
{ (a) += F((b), (c), (d)) + (k) + (i); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, k, s, i) \
{ (a) += G((b), (c), (d)) + (k) + (i); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, k, s, i) \
{ (a) += H((b), (c), (d)) + (k) + (i); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, k, s, i) \
{ (a) += I((b), (c), (d)) + (k) + (i); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
// void ToLittleEndian(uint32_t* input) {
// uint32_t tmp = *input;
// *input = ((tmp & 0xff000000) >> 24) | ((tmp & 0x00ff0000) >> 8) |
// ((tmp & 0xff) << 24) | ((tmp & 0x0000ff00) << 8);
// }
uint8_t* ProcessChunk(uint8_t* input)
{
uint32_t AA = A;
uint32_t BB = B;
uint32_t CC = C;
uint32_t DD = D;
uint32_t M[16] = {0};
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 4; j++) {
//word[i] |= (uint32_t)input[(i * 4) + j] << (24 - (j * 8));
M[i] |= (uint32_t)input[(i * 4) + j] << (32 - ((j + 1) * 8));
}
M[i] = htole32(M[i]); // is this necessary?
}
for(int i = 0; i < 16; i++) {
printf("\n word %d = 0x%08x\n", i, M[i]);
}
/* shifting rounds */
for(int i = 0; i < 64; i++) {
// error here
if (i < 16) {
FF(AA, BB, CC, DD, M[i], S[i], K[i]);
//printf("%d, %d, %u\n", M[i], S[i], K[i]);
} else if (i < 32) {
GG(AA, BB, CC, DD, M[(5 * i + 1) % 16], S[i], K[i]);
//printf("%d, %d, %u\n", M[(5 * i + 1) % 16], S[i], K[i]);
} else if (i < 48) {
HH(AA, BB, CC, DD, M[(3 * i + 5) % 16], S[i], K[i]);
//printf("%d, %d, %u\n", M[(3 * i + 5) % 16], S[i], K[i]);
} else {
II(AA, BB, CC, DD, M[(7 * i) % 16], S[i], K[i]);
//printf("%d, %d, %u\n", M[(7 * i) % 16], S[i], K[i]);
}
int Temp = DD;
DD = CC;
CC = BB;
BB = AA;
AA = Temp;
// printf("A = 0x%x\n", A);
// printf("B = 0x%x\n", B);
// printf("C = 0x%x\n", C);
// printf("D = 0x%x\n", D);
// printf("\n");
// printf("AA = 0x%x\n", AA);
// printf("BB = 0x%x\n", BB);
// printf("CC = 0x%x\n", CC);
// printf("DD = 0x%x\n", DD);
// printf("\n");
}
AA += A;
BB += B;
CC += C;
DD += D;
// uint64_t result = ((uint64_t)AA << 96) | ((uint64_t)BB << 64) |
// ((uint64_t)CC << 32) | (uint64_t)D;
uint8_t* digest = malloc(16);
for (int i = 0; i < 16; i++) {
if (i < 4) {
digest[i] = (AA >> (i*8)) & 0xff;
} else if (i < 8) {
digest[i] = (BB >> (i*8)) & 0xff;
} else if (i < 12) {
digest[i] = (CC >> (i*8)) & 0xff;
} else {
digest[i] = (DD >> (i*8)) & 0xff;
}
}
// for (int i = 0; i < 16; i++) {
// printf("%x ", result[i]);
// }
return (uint8_t*)digest;
// print out chunk
// printf("\n\n");
// for(int i = 0; i < 16; i++) {
// printf("0x%x ", M[i]);
// }
}
// abbrivation for print error
int printerr(char* errordesc)
{
printf("Error: %s\n", errordesc);
exit(1);
}
uint8_t* AddPadding(uint8_t* input, size_t input_len)
{
// compute padding length
size_t pad_len = (56 - (input_len) % 64) % 64;
// allocate required space to output buffer
uint8_t* padded = malloc(input_len + pad_len + 8);
if (padded == NULL) {
printerr("padding process cant allocate req memory");
}
// add cmd line string bytes into output
for(int i = 0; i < input_len; i++) { padded[i] = input[i]; }
// add padding bytes
for(int i = 0; i < (pad_len + 8); i++) {
if(i == 0) {
padded[input_len] = 0x80;
} else {
padded[input_len + 1 + i] = 0x00;
}
}
// changing size byte position to 0x80 when utilizing last byte
// add usigned 64 bit input length to end of the string
// if 2^64 only low order of bits are utilised
for(int i = 0; i < (64 / 8); i++) {
padded[input_len + pad_len + i] = (uint8_t)(input_len >> (64 - (i + 1) * 8) & 0xFF);
//padded[input_len + pad_len + i] = (uint8_t)(input_len >> (i * 8) & 0xFF);
}
return padded;
}
int main (int argc, char* argv[])
{
// initalise input var
uint8_t* inputstr = NULL;
if (argc !=3 || strcmp(argv[1], "--inputstr") != 0) {
printerr("usage - MD5 --inputstr (input_string)");
} else {
// point to argv[2] (3rd argument) for buffer
inputstr = (uint8_t*)argv[2];
}
// get str length
const size_t inputstr_len = strlen((char*)inputstr);
// improve later
if (inputstr_len == 0) {
printerr("inputstr < 1 char");
}
// add padding to last chunk
uint8_t* outputstr = AddPadding(inputstr, inputstr_len);
// print padding (probably will delete later)
for (int i = 0; i < inputstr_len + 1 + (64 - ((inputstr_len + 8 + 1) % 64 ) + 8); i++) {
printf("0x%02x ", outputstr[i]);
}
// break message into chunks + 1 compensation for padding
//size_t chunks = (inputstr_len / 64) + ((inputstr_len % 64 > 0) && (inputstr_len % 64 > 56));
uint8_t* chunk_result = NULL;
size_t chunks = (inputstr_len / 64) + 1 + (inputstr_len % 64 > 56);
for(int i = 0; i < chunks; i++) {
// only give req bytes
uint8_t* chunk_input = malloc(64 * sizeof(uint8_t));
for(int j = 0; j < 64; j++) {
chunk_input[j] = outputstr[i * 64 + j];
}
chunk_result = ProcessChunk(chunk_input);
// > 2 chunks??
}
// print chunk data
for (int i = 0; i < 16; i++) {
printf("%02x ", chunk_result[i]);
}
// make sure chunks cant be 0
printf("chunks: %ld\n", chunks);
// deallocate memory
free(outputstr);
free(chunk_result);
// executed sucessfully
exit(0);
}
所以我正在尝试“h”的 MD5 哈希结果,结果是
2510c39011c5be704182423e3a695e91
我的结果是
e0 64 f6 8c 9d de 68 df 1f 4b 11 d8 41 13 6b 77
我很抱歉我还没有制定排序方法但是通过比较 0x25 你可以看出它不相等 我发现了一些错误,希望这对第 150 行有帮助我在宏#define 语句中将它们全部定义为 B 我忘记了字母周围的括号