root/tools/entropy/entropy.c

Revision 1669, 3.1 kB (checked in by till, 4 months ago)

tools
- entropy: GPLv2 boilerplate

Line 
1 /* entropy.c
2  *
3  * Copyright (C) 2008 Tillmann Werner <tillmann.werner@gmx.de>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License Version 2 as
7  * published by the Free Software Foundation.  You may not use, modify or
8  * distribute this program under any other version of the GNU General
9  * Public License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  *
21  * Description: Command line utility to calculate file entropy
22  */
23
24
25 #include <fcntl.h>
26 #include <math.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33
34
35 typedef struct bstring {
36         ssize_t         len;
37         u_char          *data;
38 } bstring;
39
40
41 inline double calc_ent(bstring bstr) {
42         ssize_t         i;
43         u_int32_t       bytefreqs[256];
44         double          e;
45         double          log2;
46
47         e       = 0;
48         log2    = log(2);       // factor for changing the log base
49
50         // calculate byte frequencies
51         memset(bytefreqs, 0, 256 * sizeof(u_int32_t));
52         for (i=0; i<bstr.len; i++) bytefreqs[bstr.data[i]]++;
53
54         // calculate entropy
55         for (i=0; i<=255; i++)
56                 if (bytefreqs[i])
57                         e -= (double)bytefreqs[i]/(double)bstr.len * log((double)bytefreqs[i]/(double)bstr.len) / log2;
58
59         return(e);
60 }
61
62 inline bstring bstr_map(const char* filename) {
63         u_char buffer[BUFSIZ];
64         int fd, bytes_read, i;
65         bstring bstr;
66
67         if (filename == NULL) {
68                 fprintf(stderr, "Error - Unable to map file into memory: No filename given.\n");
69                 exit(EXIT_FAILURE);
70         }
71        
72         if ((fd = open(filename, O_RDONLY)) == -1) {
73                 fprintf(stderr, "Unable to open file %s: %m.\n", filename);
74                 exit(EXIT_FAILURE);
75         }
76
77         memset(&bstr, 0, sizeof(bstring));
78         while ((bytes_read = read(fd, buffer, BUFSIZ)) > 0) {
79                 if ((bstr.data = (void *) realloc(bstr.data, (bstr.len + bytes_read) * sizeof(u_char))) == NULL) {
80                         fprintf(stderr, "Unable to allocate memory: %m.\n");
81                         exit(EXIT_FAILURE);
82                 }
83                 memset(bstr.data+bstr.len, 0, bytes_read * sizeof(u_char));
84                 for (i=0; i<bytes_read; i++) bstr.data[bstr.len+i] = buffer[i];
85                        
86                 bstr.len += bytes_read;
87         }
88         if (bytes_read < 0) {
89                 fprintf(stderr, "Unable to read from %s: %m.\n", filename);
90                 exit(EXIT_FAILURE);
91         }
92         close(fd);
93
94         return(bstr);
95 }
96
97
98 inline void bstr_unmap(bstring bstr) {
99         free(bstr.data);
100         memset(&bstr, 0, sizeof(bstring));
101
102         return;
103 }
104
105 int main(int argc, char **argv) {
106         int     i;
107         bstring bstr;
108
109         if (argc < 2) {
110                 printf ("Usage: %s file1 [file2 file3 ...]\n", argv[0]);
111                 exit(EXIT_FAILURE);
112         }
113
114         for (i=1; i<argc; i++) {
115                 bstr = bstr_map(argv[i]);
116                 printf ("%f  %s\n", calc_ent(bstr), argv[i]);
117                 bstr_unmap(bstr);
118         }
119
120         return(EXIT_SUCCESS);
121 }
Note: See TracBrowser for help on using the browser.