【问题标题】:I'm unable to calculate the entropy of a .exe file我无法计算 .exe 文件的熵
【发布时间】:2014-09-30 21:23:37
【问题描述】:

我正在尝试通过将 .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();
}

【问题讨论】:

  • 天哪。你的缩进怎么了?那是无法阅读的。
  • 当要求人们阅读您的代码时,请更好地格式化。缩进、运算符周围的空格(例如for(i = 0; i &lt; 256; i++))等
  • @MattiVirkkunen ,@Almo 谢谢大家的建议
  • 新颖的想法——打印出一些中间结果,例如。 'i' 和 'histlen',或者使用实际的调试器来检查它们的值。
  • 您正在尝试将 exe 文件解析为数字文本文件。不要使用 fscanf。使用 fgetc 或 fread 读取字节。

标签: c entropy


【解决方案1】:
while (fscanf(file,"%d",&num)>0)

这会读取编码为前导空格、可选符号和数字序列的数字。一旦在您的文件中遇到其他字符(可能是第一个字节),您的循环就会停止。您需要使用getcfread 读取原始字节。

另外,在向 StackOverflow 提交问题之前,请考虑进行最基本的调试。当然,您在该循环中的 printf 从未打印过任何内容,但您没有在问题中提及这一点,显然也没有调查原因。

其他一些问题:

#define MAXLEN 100

这从未使用过。


void main() 

这不是main 的有效定义。使用

int main(void)

char S[100];

如果输入包含超过 100 个字符,则您的行为未定义,而 .exe 文件肯定会。您确实应该在读取它们时将字节输入直方图计算,而不是将它们存储在缓冲区中。最简单的方法是使wherecharhistlen 成为全局变量,但您也可以将所需的所有内容放入结构中,并将指向该结构的指针与每个字节一起传递给makehist,然后再次将指针传递给该结构到entropy


FILE*file = fopen("freq.exe","r");

二进制文件必须用“rb”打开(在 linux 上没关系,但在 Windows 上)。 另外,你应该检查fopen是否成功。


hist=(int*)calloc(i,sizeof(int));

hist 应该有 256 个元素。如果你先分配它,那么你可以按照上面读取的方式处理每个字节。


如果文件为空,则在 entropy 中除以零...您应该检查 len == 0。


wherechar[(int)S[i]] 如果文件包含带有负值的字符,则为未定义的行为,因为它肯定会。您应该使用unsigned char 而不是char,这样就不需要强制转换了。

【讨论】:

    【解决方案2】:

    这一行似乎在读数字:

    fscanf(file,"%d",&num)
    

    但我真的不希望在 EXE 文件中找到很多数字。 它们是所有不同类型的随机字节值。

    数字只是数字 0-9(以及 -+ 符号)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-02
      • 2020-04-19
      • 2015-01-31
      • 2016-02-05
      • 2014-05-27
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多