求助:向父进程发送Signal无效,MD5解密程序开发遇阻
Hey there! Let's figure out why your signal-based approach isn't working and get your MD5 cracker up and running properly with pipes.
First off: signals are not meant for passing complex data like strings or match results. Signals only carry a single integer value, they're unreliable (can be lost if multiple are sent quickly), and they're designed for event notifications (like "process got interrupted")—not for sending actual data between processes. Pipes are the right tool here, and I'll show you how to set them up correctly.
Here's the step-by-step fix for your setup:
We'll use two pipes: one for the parent to send words to the child, and another for the child to send match results back to the parent. This keeps data flows separate and avoids blocking issues.
Example Working Code
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <openssl/md5.h> #include <sys/wait.h> // Replace this with your target MD5 hash #define TARGET_MD5 "5d41402abc4b2a76b9719d911017c592" // MD5 of "hello" // Helper function to compute MD5 hash of a string void compute_md5(const char *str, char *result) { unsigned char digest[MD5_DIGEST_LENGTH]; MD5((unsigned char*)str, strlen(str), digest); // Convert binary digest to hex string for(int i = 0; i < MD5_DIGEST_LENGTH; i++) { sprintf(result + (i*2), "%02x", digest[i]); } result[32] = '\0'; // Null-terminate the 32-character hex string } int main() { int word_pipe[2]; // Parent writes words here, child reads from it int result_pipe[2]; // Child writes results here, parent reads from it // Create both pipes before forking (so both processes inherit them) if(pipe(word_pipe) == -1 || pipe(result_pipe) == -1) { perror("Failed to create pipe"); exit(EXIT_FAILURE); } pid_t pid = fork(); if(pid == -1) { perror("Fork failed"); exit(EXIT_FAILURE); } if(pid == 0) { // ---------------- CHILD PROCESS ---------------- // Close the pipe ends we don't need close(word_pipe[1]); // Child doesn't write to the word pipe close(result_pipe[0]); // Child doesn't read from the result pipe char buffer[256]; ssize_t bytes_read; // Read words from the parent until the pipe is closed while((bytes_read = read(word_pipe[0], buffer, sizeof(buffer)-1)) > 0) { buffer[bytes_read] = '\0'; // Strip newline characters (from fgets in parent) buffer[strcspn(buffer, "\n")] = '\0'; char computed_md5[33]; compute_md5(buffer, computed_md5); // Check if we found a match if(strcmp(computed_md5, TARGET_MD5) == 0) { // Send the matching word back to parent (include null terminator) write(result_pipe[1], buffer, strlen(buffer)+1); break; // Exit early once we find a match } } // Clean up child's pipe ends close(word_pipe[0]); close(result_pipe[1]); exit(EXIT_SUCCESS); } else { // ---------------- PARENT PROCESS ---------------- // Close unused pipe ends close(word_pipe[0]); // Parent doesn't read from the word pipe close(result_pipe[1]); // Parent doesn't write to the result pipe // Open your dictionary file FILE *dict_file = fopen("dictionary.txt", "r"); if(!dict_file) { perror("Failed to open dictionary file"); exit(EXIT_FAILURE); } char word[256]; // Read each word from the file and send to child while(fgets(word, sizeof(word), dict_file) != NULL) { write(word_pipe[1], word, strlen(word)); } // Close the write end of the word pipe to signal child no more data close(word_pipe[1]); // Read result from child char match_result[256]; ssize_t result_bytes = read(result_pipe[0], match_result, sizeof(match_result)-1); if(result_bytes > 0) { match_result[result_bytes] = '\0'; printf("Success! Found matching word: %s\n", match_result); } else { printf("No matching word found in the dictionary.\n"); } // Wait for child process to finish cleanly wait(NULL); // Clean up parent's resources close(result_pipe[0]); fclose(dict_file); } return 0; }
Key Things to Note:
- Dual Pipes: Using two separate pipes prevents read/write blocking issues. Each process only uses the pipe ends it needs.
- Proper Pipe Closure: Closing unused pipe ends is critical—if you leave a write end open,
read()will block forever waiting for more data. - Signal Limitations: As I mentioned earlier, signals can't reliably pass strings. Even if you tried to use a signal to notify the parent "a match was found", you'd still need a pipe to send the actual word. Pipes solve both problems in one go.
- MD5 Handling: The helper function converts the binary MD5 digest to a hex string, which matches the format of typical MD5 hashes we compare against.
Compilation Note:
You'll need to link the OpenSSL library when compiling:
gcc md5_cracker.c -o md5_cracker -lcrypto
内容的提问来源于stack exchange,提问作者Jose Lopez Rodriguez

