我试图通过将其作为输入来计算.exe文件的熵。但是,我得到零值而不是答案。
文件的熵可以理解为文件中每个字符的(pi * log(pi))的总和。我试图计算.exe文件的熵。但是,我最终得到了一个' 0'。 ' .exe'文件肯定有输出。
以下是我的代码。
#include <stdio.h>
#include <stdlib.h>
#include "stdbool.h"
#include <string.h>
#include <conio.h>
#include <math.h>
#define MAXLEN 100
int makehist( char *S, int *hist, int len) {
int wherechar[256];
int i,histlen;
histlen=0;
for (i=0;i<256;i++)
wherechar[i]=-1;
for (i=0;i<len;i++) {
if (wherechar[(int)S[i]]==-1) {
wherechar[(int)S[i]]=histlen;
histlen++;
}
hist[wherechar[(int)S[i]]]++;
}
return histlen;
}
double entropy(int *hist, int histlen, int len) {
int i;
double H;
H=0;
for (i=0;i<histlen;i++) {
H-=(double)hist[i]/len*log((double)hist[i]/len);
}
return H;
}
void main() {
char S[100];
int len,*hist,histlen;
int num;
double H;
int i=0;
int count =0;
FILE*file = fopen("freq.exe","r");
while (fscanf(file,"%d",&num)>0)
{
S[i]=num;
printf("%d",S[i]);
i++;
}
hist=(int*)calloc(i,sizeof(int));
histlen=makehist(S,hist,i);
H=entropy(hist,histlen,i);
printf("%lf\n",H);
getch();
}
答案 0 :(得分:3)
while (fscanf(file,"%d",&num)>0)
这会读取编码为前导空格,可选符号和数字序列的数字。一旦在文件中遇到其他字符(可能是第一个字节),您的循环就会停止。您需要使用getc
或fread
读取原始字节。
另外,在向StackOverflow提交问题之前,请考虑进行最基本的调试。当然你在那个循环中的printf从来没有打印任何东西,但你在你的问题中没有提到这一点,显然没有调查原因。
其他一些问题:
#define MAXLEN 100
从未使用过。
void main()
这不是main
的有效定义。使用
int main(void)
char S[100];
如果输入包含超过100个字符,则会有未定义的行为,并且肯定会有.exe文件。你应该在读取它们时将字节输入直方图计算,而不是将它们存储在缓冲区中。最简单的是使wherechar
和histlen
全局变量,但您也可以将所需的所有内容放入结构中,并将指向结构的指针与每个字节一起传递给makehist
,并再次将指向结构的指针传递给entropy
。
FILE*file = fopen("freq.exe","r");
必须使用&#34; rb&#34;打开二进制文件(在Linux上并不重要,但在Windows上)。
此外,您应该检查fopen
是否成功。
hist=(int*)calloc(i,sizeof(int));
hist
应该有256个元素。如果先分配它,那么你可以处理每个字节,如上所述。
如果文件为空,则在entropy
中除以零...您应该检查len
== 0。
wherechar[(int)S[i]]
是未定义的行为,如果文件具有负值的字符,肯定会。您应该使用unsigned char
代替char
,然后不需要演员。
答案 1 :(得分:1)
这一行似乎是在读数字:
fscanf(file,"%d",&num)
但我真的不希望在EXE文件中找到很多数字。 它们是所有不同类型的随机字节值。
数字只是数字0-9
(以及-
和+
符号。