在C中创建md5sum
我试图在C程序中使用在C中创建md5sum,c,md5sum,C,Md5sum,我试图在C程序中使用md5sum命令,现在我使用dirent.h获取文件夹中的所有文件,现在,我想获取所有这些文件的md5,我正在这样做: #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <unistd.h&
md5sum
命令,现在我使用dirent.h
获取文件夹中的所有文件,现在,我想获取所有这些文件的md5,我正在这样做:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <dirent.h>
int main(void){
char *word = ".gz";
int i=0;
char *word2 = ".";
char *word3 = "..";
unsigned int md5;
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d) {
while ((dir = readdir(d)) != NULL)
{
if((strstr(dir->d_name, word) == NULL) && (strcmp(dir->d_name, word2) != 0) && (strcmp(dir->d_name, word3)!= 0)) {
md5 = system("md5sum dir->d_name");
printf("The md5 of %s is %d\n", dir->d_name, md5);
}
}
}
return(0);
}
你能解释一下为什么会这样吗?谢谢
系统
不返回命令的输出。要获得命令的输出,您需要创建一个进程,并将标准输出流绑定到一个文件描述符,以便在另一个进程中读取数据。有关如何执行此操作的示例,请参阅管道
手册页(第2节)
另一种选择是使用提供MD5实现的库(例如OpenSSL)。的手册页(第3节)提供了一个示例
另一个问题是,您的代码试图计算
d->d\u name
的摘要,而不是d->d\u name
中的文件名。您可以将sprintf
或strncat
与适当大小的缓冲区(即静态字符串部分的长度md5sum
加上文件名的最大大小(通常为256字节,可能因库实现和文件系统而异)加上另一个字节,以安全终止字符串(因为某些实现可能会在d->d_name
中报告未终止的字符串)。请注意,如果使用库进行摘要计算,则这不适用,因为库使用文件名或需要将文件内容传递给库函数(例如EVP_digestude
).系统
不返回命令的输出。要获得命令的输出,您需要创建一个进程,并将标准输出流绑定到一个文件描述符,您可以在另一个进程中读取数据。有关如何执行此操作的示例,您可以参考管道
手册页(第2节)
另一种选择是使用提供MD5实现的库(例如OpenSSL)。的手册页(第3节)提供了一个示例
另一个问题是,您的代码试图计算
d->d_name
的摘要,而不是d->d_name
中的文件名。您可以使用sprintf
或strncat
和适当大小的缓冲区(即静态字符串部分md5sum
的长度加上文件名的最大大小)(通常为256字节,可能因库实现和文件系统而异)加上另一个字节以安全终止字符串(因为某些实现可能在d->d_name
中报告未终止的字符串)。请注意,如果您使用库进行摘要计算,则这不适用,因为库使用文件名或您需要将文件内容传递给库函数(例如,EVP\u DigestUpdate
).系统函数不会返回您的想法。系统
用于启动命令,当该命令完成时,它(通常)会以退出代码退出。这是您捕获的值
您需要的是命令的输出,而不是它的返回值。因此,您需要的是
popen
,它允许您启动一些外部命令并通过管道对其进行读/写。例如,请参见。system函数不会返回您所想的内容。system
用于启动命令,并且当该命令发出时d完成后,它(通常)会以退出代码退出。这是您捕获的值
您需要的是命令的输出,而不是它的返回值。因此,您需要的是
popen
,它允许您启动一些外部命令并通过管道对其进行读/写。例如,请参见。第一个问题是,您启动了一个新的shell进程,执行“md5sum dir->d_name”
,这意味着它对名为dir->d_name
的“文件”执行md5
,而不是使用从readdir获得的值
所以您可以添加一个temp变量,并在运行系统之前准备其中的命令
limits.h
适用于Linux,如果需要,请调整它以获得路径的最大长度
...
#include <linux/limits.h>
char temp[PATH_MAX];
加
至于另一个问题(系统不会返回md5字符串),这将在目录中显示文件的md5。您只需删除printf…第一个问题是您启动了一个新的shell进程,执行
“md5sum dir->d_name”
,这意味着它对“文件”执行md5
命名为dir->d_name
,而不是使用从readdir获得的值
所以您可以添加一个temp变量,并在运行系统之前准备其中的命令
limits.h
适用于Linux,如果需要,请调整它以获得路径的最大长度
...
#include <linux/limits.h>
char temp[PATH_MAX];
加
至于另一个问题(系统不会返回md5字符串),这将在目录中显示文件的md5。您只需删除printf…在C中没有返回外部命令输出的命令,但存在
popen
您可以将命令作为文件*
打开并从中读取输出。这是您可以执行的方法,在t中对此进行了详细说明他编码
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main(void)
{
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d == NULL)
return -1;
while ((dir = readdir(d)) != NULL)
{
char command[sizeof dir->d_name + 10];
struct stat st;
FILE *pipe;
if (stat(dir->d_name, &st) == -1)
continue;
/* check if the entry is a directory, md5sum does not work with them */
if (S_ISDIR(st.st_mode) != 0)
continue;
/*
* md5sum dir->d_name will pass `dir->d_name` as the argument to the md5sum command,
* we need to build the command string, I like snprintf in this case
*/
snprintf(command, sizeof command, "md5sum \"%s\"", dir->d_name);
/*
* Open the pipe, it will execute the new command in a new process (fork)
* and create a pipe for communication with the current porcess
*/
pipe = popen(command, "r");
if (pipe != NULL)
{
char md5[33];
/* read the md5 digest string from the command output */
fread(md5, 1, sizeof md5 - 1, pipe);
/* append a null terminator */
md5[sizeof md5 - 1] = '\0';
printf("The md5 of %s is %s\n", dir->d_name, md5);
}
/* close the pipe */
pclose(pipe);
}
/* you should always call closedir() if opendir() succeded */
closedir(d);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
DIR*d;
结构方向*dir;
d=opendir(“.”);
如果(d==NULL)
返回-1;
而((dir=readdir(d))!=NULL)
{
char命令[sizeof dir->d_name+10];
结构统计;
文件*管道;
if(stat(dir->d_name,&st)=-1)
继续;
/*检查条目是否为目录,md5sum不适用于它们*/
如果(S_ISDIR(st.st_模式)!=0)
继续;
/*
*md5sum dir->d_name将把'dir->d_name'作为参数传递给md5sum命令,
*我们需要构建命令字符串,在本例中我喜欢snprintf
*/
snprintf(命令,sizeof命令,“md5sum\%s\”,dir->d
strcpy(temp, "md5sum ");
strcat(temp, dir->d_name);
system(temp);
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main(void)
{
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d == NULL)
return -1;
while ((dir = readdir(d)) != NULL)
{
char command[sizeof dir->d_name + 10];
struct stat st;
FILE *pipe;
if (stat(dir->d_name, &st) == -1)
continue;
/* check if the entry is a directory, md5sum does not work with them */
if (S_ISDIR(st.st_mode) != 0)
continue;
/*
* md5sum dir->d_name will pass `dir->d_name` as the argument to the md5sum command,
* we need to build the command string, I like snprintf in this case
*/
snprintf(command, sizeof command, "md5sum \"%s\"", dir->d_name);
/*
* Open the pipe, it will execute the new command in a new process (fork)
* and create a pipe for communication with the current porcess
*/
pipe = popen(command, "r");
if (pipe != NULL)
{
char md5[33];
/* read the md5 digest string from the command output */
fread(md5, 1, sizeof md5 - 1, pipe);
/* append a null terminator */
md5[sizeof md5 - 1] = '\0';
printf("The md5 of %s is %s\n", dir->d_name, md5);
}
/* close the pipe */
pclose(pipe);
}
/* you should always call closedir() if opendir() succeded */
closedir(d);
return 0;
}