/***************************************************************************/ /* */ /* Bitstat - generate bit-wise [and byte-wise] statistics of a file */ /* */ /* Usage: bitstat [-v] file (normal usage) */ /* or: bitstat [-v] < file */ /* or: type file | bitstat [-v] */ /* or: bitstat [-v] (keyboard input (terminate with ^Z)) */ /* */ /* Version: 1.0 */ /* Platform: DOS (easily transportable) */ /* Compiler: gcc */ /* Date: 07/09/96 */ /* License: Freeware */ /* Author: Winston Rayburn */ /* */ /***************************************************************************/ #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #define INPUT_BUFFER_SIZE 1024 /* in bytes */ #define TRUE (1==1) #define FALSE (1==0) #define USAGE printf("%s: Usage: %s [-v] file\n", argv[0], argv[0]); \ exit(1) /***************************************************************************/ main (argc, argv) int argc; char *argv[]; { float set_ratio, deviance_from_unity; float bit_percentage[8], byte_percentage[256]; float average_byte_count, average_byte_percentage; float ones_bit_percentage, zeros_bit_percentage; unsigned int bytes = 0, ones = 0, zeros; unsigned int i, got; unsigned char uc; int in; unsigned int byte_count[256] = {0}; unsigned int bit_count[8] = {0}; unsigned int bits; char *p; char verbose = FALSE; char c[INPUT_BUFFER_SIZE]; /***************************************************************************/ for (i=1; i<argc; i++) { p=argv[i]; if (*p++ == '-') { switch (*p) { case 'v': case 'V': verbose = TRUE; break; default: USAGE; break; } } } p = argv[argc-1]; if ((argc > 1) && (*p != '-')) { //--> in = open(argv[argc-1], O_RDONLY|O_BINARY); in = open(argv[argc-1], "rb"); if (in < 0) { printf("%s: Error opening %s\n", argv[0], argv[argc-1]); USAGE; } } else in = 0; while ((got = read(in, c, INPUT_BUFFER_SIZE)) > 0) { bytes += got; for(i=0; i<got; i++) { uc = (unsigned char) c[i]; byte_count[uc]++; if (uc & 0x01) bit_count[0]++; if (uc & 0x02) bit_count[1]++; if (uc & 0x04) bit_count[2]++; if (uc & 0x08) bit_count[3]++; if (uc & 0x10) bit_count[4]++; if (uc & 0x20) bit_count[5]++; if (uc & 0x40) bit_count[6]++; if (uc & 0x80) bit_count[7]++; } } if (bytes == 0) { printf("%s: File %s empty\n", argv[0], in==0?"stdin":argv[argc-1]); USAGE; } else close(in); for (i=0; i<8; i++) { ones += bit_count[i]; bit_percentage[i] = (float)100.0*bit_count[i]/bytes; } bits = bytes*8; zeros = bits - ones; ones_bit_percentage = (float)100.0*ones/(float)bits; zeros_bit_percentage = (float)100.0*zeros/(float)bits; set_ratio = (float)ones/zeros; deviance_from_unity = set_ratio-1; average_byte_count = (float)bytes/(float)256.0; average_byte_percentage = (float)100.0*1.0/256.0; for (i=0; i<256; i++) { byte_percentage[i] = (float)100*byte_count[i]/bytes; } printf("%s contains %d bytes (%d bits)\n", in==0?"stdin":argv[argc-1], bytes, bits); if (verbose) { printf("\n BYTE ANALYSIS\n\n"); printf(" Byte Count Percentage\n"); printf(" ---- ----- ----------\n"); printf(" norm %8.1f %10.6f\n", average_byte_count, average_byte_percentage); for (i=0; i<256; i++) { printf("%c %3d %8d %10.6f\n", isprint(i)?i:' ', i, byte_count[i], byte_percentage[i]); } } printf("\n BIT ANALYSIS\n\n"); printf("Value Count Percentage\n"); printf("----- ----- ----------\n"); printf(" one %8d %10.6f\n", ones, ones_bit_percentage); printf(" zero %8d %10.6f\n", zeros, zeros_bit_percentage); printf("\n Bit Count Percentage\n"); printf(" --- ----- ----------\n"); for (i=0; i<8; i++) { if (i==0) printf("msb"); else if (i==7) printf("lsb"); else printf(" "); printf("%2d %8d %10.6f\n", 7-i, bit_count[7-i], bit_percentage[7-i]); } printf("\n1/0 ratio %9.6f\n", set_ratio); printf("Deviance from unity %9.6f\n", deviance_from_unity); }